使用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可跨平台实现获取按键的方法
Mar 05 Python
用Python实现通过哈希算法检测图片重复的教程
Apr 02 Python
Python中用PIL库批量给图片加上序号的教程
May 06 Python
详解python之配置日志的几种方式
May 22 Python
Python 稀疏矩阵-sparse 存储和转换
May 27 Python
Python3数据库操作包pymysql的操作方法
Jul 16 Python
python pandas写入excel文件的方法示例
Jun 25 Python
Pandas之ReIndex重新索引的实现
Jun 25 Python
Python图像处理库PIL的ImageDraw模块介绍详解
Feb 26 Python
jupyter notebook实现显示行号
Apr 13 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
Jan 09 Python
python神经网络学习 使用Keras进行回归运算
May 04 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程序中的常见漏洞进行攻击(下)
2006/10/09 PHP
php下实现农历日历的代码
2007/03/07 PHP
微信营销平台系统?刮刮乐的开发
2014/06/10 PHP
PHP生成等比缩略图类和自定义函数分享
2014/06/25 PHP
php each 返回数组中当前的键值对并将数组指针向前移动一步实例
2016/11/22 PHP
HTML页面如何象ASP一样接受参数
2007/02/07 Javascript
再次分享18个非常棒的jQuery表格插件
2011/04/10 Javascript
JS实现定时页面弹出类似QQ新闻的提示框
2013/11/07 Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
2014/11/23 Javascript
AngularJS递归指令实现Tree View效果示例
2016/11/07 Javascript
详解微信小程序input标签正则初体验
2018/08/18 Javascript
vue elementUI table表格数据 滚动懒加载的实现方法
2019/04/04 Javascript
vue中使用v-model完成组件间的通信
2019/08/22 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
layui table数据修改的回显方法
2019/09/04 Javascript
python在每个字符后添加空格的实例
2018/05/07 Python
Django unittest 设置跳过某些case的方法
2018/12/26 Python
基于spring boot 日志(logback)报错的解决方式
2020/02/20 Python
windows下的pycharm安装及其设置中文菜单
2020/04/23 Python
新西兰网上购物,折扣店:BestDeals.co.nz
2019/03/20 全球购物
100%羊绒:NakedCashmere
2020/08/26 全球购物
什么是.net的Remoting技术
2016/07/08 面试题
工程造价自荐信
2013/10/09 职场文书
毕业生大学生活自我总结
2014/01/31 职场文书
《夏夜多美》教学反思
2014/02/17 职场文书
初中学校军训方案
2014/05/09 职场文书
2014校长四风问题对照检查材料思想汇报
2014/09/16 职场文书
婚礼女方父母答谢词
2015/01/04 职场文书
车队安全员岗位职责
2015/02/15 职场文书
史上最牛辞职信
2015/05/13 职场文书
学校少先队工作总结
2015/08/12 职场文书
中学生运动会广播稿
2015/08/19 职场文书
人身损害赔偿协议书
2016/03/22 职场文书
Python基础详解之邮件处理
2021/04/28 Python
Android自定义ScrollView实现阻尼回弹
2022/04/01 Java/Android
python数据分析之单因素分析线性拟合及地理编码
2022/06/25 Python