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

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
(0)

相关推荐

  • Python求导数的方法

    本文实例讲述了Python求导数的方法.分享给大家供大家参考.具体实现方法如下: def func(coeff): sum='' for key in coeff: sum=sum+'+'+str(key)+'*'+'x'+'**'+str(coeff[key]) return sum[1:] from sympy import * from sympy.core.sympify import SympifyError expr = func({2:0,3:1,4:2,5:7}) x = Sym

  • Python求算数平方根和约数的方法汇总

    一.求算术平方根 a= x=int(raw_input('Enter a number:')) if x >= : while a*a < x: a = a + if a*a != x: print x,'is not a perfect square' else: print a else: print x,'is a negative number' 二.求约数 方法一: divisor = [ ] x=int(raw_input('Enter a number:')) i= while

  • python里对list中的整数求平均并排序

    问题 定义一个int型的一维数组,包含40个元素,用来存储每个学员的成绩,循环产生40个0~100之间的随机整数, (1)将它们存储到一维数组中,然后统计成绩低于平均分的学员的人数,并输出出来. (2)将这40个成绩按照从高到低的顺序输出出来. 解决(python) #! /usr/bin python #coding:utf-8 from __future__ import division #实现精确的除法,例如4/3=1.333333 import random def make_scor

  • python求素数示例分享

    复制代码 代码如下: # 判断是否是素数def is_sushu(num): res=True for x in range(2,num-1):  if num%x==0:   res=False   return res return res # 打印出素数列表print ([x for x in range(1000) if is_sushu(x)])

  • 利用python求相邻数的方法示例

    前言 本文主要给大家介绍了关于利用python求相邻数的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 什么是相邻数? 比如5,相邻数为4和6,和5相差1的数,连续相差为1的一组数 需求: 遍历inputList 所有数字,取出所有数字,判断是否有相邻数, 不相邻数字 和 相邻数字 都以 "数组"形式 添加到 outputList 中, 并且 每个"数组" 里 第一位 递减 补全两位数,末位 递增 补全两位数, 每一个数不能小于0, 不能大

  • python求斐波那契数列示例分享

    复制代码 代码如下: def getFibonacci(num): res=[0,1] a=0 b=1 for x in range(0,num):  if x==a+b:   res.append(x)   a,b=b,a+b return res res=getFibonacci(1000)print(res) #递归a=[0,1]qian=0def fibna(num,qian): print(num) he=num+qian if he<1000:  a.append(he)  qian

  • python求众数问题实例

    本文实例讲述了python求众数问题的方法,是一个比较典型的应用.分享给大家供大家参考.具体如下: 问题描述: 多重集中重数最大的元素称为众数...就是一个可以有重复元素的集合,在这个集合中重复的次数最多的那个数就叫它的众数... 如S = [1,2,2,2,3,5] 重数是2,其重数为3 实例代码如下: list_num = [] list_num_count = 0 dict_num ={} #从文件读入,文件第一行为集合中元素的个数,以后每一行为一个元素 list_num_count =

  • Python实现求最大公约数及判断素数的方法

    本文实例讲述了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: prin

  • Python编程实现数学运算求一元二次方程的实根算法示例

    本文实例讲述了Python编程实现数学运算求一元二次方程的实根算法.分享给大家供大家参考,具体如下: 问题: 请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程:ax² + bx + c = 0的两个解. 实现代码: #!/usr/bin/env python # -*- coding: utf-8 -*- import math def quadratic(a,b,c): if a == 0: raise TypeError('a不能为0') if not is

  • Python实现高效求解素数代码实例

    素数是编程中经常需要用到的. 作为学习Python的示例,下面是一个高效求解一个范围内的素数的程序,不需要使用除法或者求模运算. #coding:utf-8 #设置python文件的编码为utf-8,这样就可以写入中文注释 def primeRange(n): myArray=[1 for x in range(n+1)] ##列表解析,生成长度为(n+1)的列表,每个数值都为1 myArray[0]=0 myArray[1]=0 startPos=2 while startPos <= n:

  • Python基于二分查找实现求整数平方根的方法

    本文实例讲述了Python基于二分查找实现求整数平方根的方法.分享给大家供大家参考,具体如下: x=int(raw_input('please input a int:')) if x<0: retrun -1 low=0 high=x ans=(low+high)/2.0 sign=ans while ans**2 !=x: if ans**2>x: high=ans else: low=ans ans=(low+high)/2.0 if sign==ans: break print ans

  • Python实现利用最大公约数求三个正整数的最小公倍数示例

    本文实例讲述了Python实现利用最大公约数求三个正整数的最小公倍数.分享给大家供大家参考,具体如下: 在求解两个数的小公倍数的方法时,假设两个正整数分别为a.b的最小公倍数为d,最大公约数为c.存在这样的关系d=a*b/c.通过这个关系式,我们可以快速的求出三个正整数的最小公倍数. def divisor(a,b): c = a%b while c>0: a=b b=c c=a%b return b x1 = input("input1:") x2 = input("

随机推荐