使用Python求解最大公约数的实现方法


Posted in Python onAugust 20, 2015

1. 欧几里德算法

欧几里德算法又称辗转相除法, 用于计算两个整数a, b的最大公约数。其计算原理依赖于下面的定理:
定理: gcd(a, b) = gcd(b, a mod b)

证明:
  a可以表示成a = kb + r, 则r = a mod b
  假设d是a, b的一个公约数, 则有  d|a, d|b, 而r = a - kb, 因此d|r。
  因此,d是(b, a mod b)的公约数。
  加上d是(b,a mod b)的公约数,则d|b, d|r, 但是a = kb + r,因此d也是(a, b)的公约数。
  因此,(a, b) 和(a, a mod b)的公约数是一样的,其最大公约数也必然相等,得证。

欧几里德的Python语言描述为:

def gcd(a, b):
 if a < b:
  a, b = b, a

 while b != 0:
  temp = a % b
  a = b
  b = temp

 return a

2. Stein算法
欧几里德算法是计算两个数最大公约数的传统算法,无论是理论,还是从效率上都是很好的。但是他有一个致命的缺陷,这个缺陷只有在很大的素数时才会显现出来。
考虑现在的硬件平台,一般整数最多也就是64位, 对于这样的整数,计算两个数值就的模很简单的。对于字长为32位的平台,计算两个不超过32位的整数的模,只需要一个指令周期,而计算64位以下的整数模,也不过几个周期而已。但是对于更大的素数,这样的计算过程就不得不由用户来设计,为了计算两个超过64位的整数的模,用户也许不得不采用类似于多位除法手算过程中的试商法,这个过程不但复杂,而且消耗了很多CPU时间。对于现代密码算法,要求计算128位以上的素数的情况比比皆是,设计这样的程序迫切希望能够抛弃除法和取模。
Stein算法由J.Stein 1961年提出,这个方法也是计算两个数的最大公约数。和欧几里德算法不同的是,Stein算法只有整数的移位和加减法,这对于程序设计者是一个福音。
为了说明Stein算法的正确性,首先必须注意到以下结论:
  gcd(a, a) = a, 也就是一个数和他自己的公约数是其自身。
  gcd(ka, kb) = k * gcd(a, b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个偶数的最大公约数比如能被2整除。
Stein算法的python实现如下:

def gcd_Stein(a, b):  
  if a < b:
    a, b = b, a
  if (0 == b):
    return a
  if a % 2 == 0 and b % 2 == 0:
    return 2 * gcd_Stein(a/2, b/2)
  if a % 2 == 0:
    return gcd_Stein(a / 2, b)
  if b % 2 == 0:
    return gcd_Stein(a, b / 2)
  
  return gcd_Stein((a + b) / 2, (a - b) / 2)

3. 一般求解实现

核心代码很简单:

def gcd(a, b):
if b == 0:return a
return gcd(b, a % b)

附上一个用Python实现求最大公约数同时判断是否是素数的一般方法:
程序如下:

#!/usr/bin/env python 
 
def showMaxFactor(num): 
  count = num / 2  
  while count > 1: 
    if num % count == 0: 
      print 'largest factor of %d is %d' % (num, count) 
      break    #break跳出时会跳出下面的else语句 
    count -= 1 
  else: 
    print num, "is prime" 
 
for eachNum in range(10,21): 
  showMaxFactor(eachNum)

输出如下:

largest factor of 10 is 5
11 is prime
largest factor of 12 is 6
13 is prime
largest factor of 14 is 7
largest factor of 15 is 5
largest factor of 16 is 8
17 is prime
largest factor of 18 is 9
19 is prime
largest factor of 20 is 10
Python 相关文章推荐
Python常用模块用法分析
Sep 08 Python
python连接oracle数据库实例
Oct 17 Python
Python合并两个字典的常用方法与效率比较
Jun 17 Python
python编程开发之日期操作实例分析
Nov 13 Python
Python实现的双色球生成功能示例
Dec 18 Python
解决python报错MemoryError的问题
Jun 26 Python
Python设计模式之策略模式实例详解
Jan 21 Python
python多线程同步实例教程
Aug 11 Python
Django Serializer HiddenField隐藏字段实例
Mar 31 Python
Python3.7 读取音频根据文件名生成脚本的代码
Apr 07 Python
解决import tensorflow导致jupyter内核死亡的问题
Feb 06 Python
解决numpy数组互换两行及赋值的问题
Apr 17 Python
使用Python3编写抓取网页和只抓网页图片的脚本
Aug 20 #Python
详解Python3中yield生成器的用法
Aug 20 #Python
Python中集合的内建函数和内建方法学习教程
Aug 19 #Python
深入解析Python中的集合类型操作符
Aug 19 #Python
Python中的集合类型知识讲解
Aug 19 #Python
深入理解Python中字典的键的使用
Aug 19 #Python
详解Python中映射类型的内建函数和工厂函数
Aug 19 #Python
You might like
PHP脚本的10个技巧(3)
2006/10/09 PHP
写出高质量的PHP程序
2012/02/04 PHP
php操作mysql数据库的基本类代码
2014/02/25 PHP
php使用正则验证中文
2016/04/06 PHP
php常用字符函数实例小结
2016/12/29 PHP
thinkPHP5.0框架独立配置与动态配置方法
2017/03/17 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
JMenuTab简单使用说明
2008/03/13 Javascript
js 禁止选择功能实现代码(兼容IE/Firefox)
2010/04/23 Javascript
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
2010/05/25 Javascript
jQuery使用attr()方法同时设置多个属性值用法实例
2015/03/26 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
2015/12/29 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
使用AngularJS编写多选按钮选中时触发指定方法的指令代码详解
2017/07/24 Javascript
JavaScript实现打印星型金字塔功能实例分析
2017/09/27 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
Python struct.unpack
2008/09/06 Python
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
2015/05/15 Python
python基于multiprocessing的多进程创建方法
2015/06/04 Python
fastcgi文件读取漏洞之python扫描脚本
2017/04/23 Python
python3学生名片管理v2.0版
2018/11/29 Python
Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统
2019/09/05 Python
python实现自动化报表功能(Oracle/plsql/Excel/多线程)
2019/12/02 Python
opencv+python实现均值滤波
2020/02/19 Python
python实现程序重启和系统重启方式
2020/04/16 Python
详解Python yaml模块
2020/09/23 Python
英国最大的在线蜡烛商店:Candles Direct
2019/03/26 全球购物
法院实习人员自我鉴定
2013/09/26 职场文书
机械设计及其自动化专业推荐信
2013/10/31 职场文书
小学生期末自我鉴定
2014/01/19 职场文书
初中科学教学反思
2014/01/21 职场文书
《永远的白衣战士》教学反思
2014/04/25 职场文书
禁止高声喧哗的标语
2014/06/11 职场文书
学雷锋的心得体会
2014/09/04 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
Spring Bean的实例化之属性注入源码剖析过程
2021/06/13 Java/Android