遍历法
m=int(raw_input('please input a integer m'))
n=int(raw_input('please input a integer n'))
import sys, os
from time import clock
start = clock()
if m<n:
m,n = n,m
q = 1
max = 1
tiple = m*n
for i in range(2,n+1):
if(n%i == 0 and m%i == 0):
max = i
print 'The max common divisor is %s'%max
print 'The min common multiple is %s'%(tiple/max)
print "End At: " + str((clock()-start)*1000)
通过遍历最小值n来计算出最大公约数max
而最小公倍数为 (m/max) *( n/max) *max =m*n/max
辗转相除法
如果数过大,则计算时间又太长,欧几里得提出的辗转相除法则可以大幅度降低运算时间。
即两个数的最大公约数,为两数中最小数和两数相除所得余数的最大公约数。
m= p1*n+q1
n=p2*q1+p2
...
当pn为0时得到最大公约数
上文的循环可改为
while q!=0:
q = m % n
m = n
n = q<span style="white-space:pre"> </span> max = m
m就是最大公约数
更相减损法
更相减损法:也叫更相减损术,是出自《九章算术》的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合。
《九章算术》是中国古代的数学专著,其中的“更相减损术”可以用来求两个数的最大公约数,即“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。”
翻译成现代语言如下:
第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。
翻译成现代语言如下:
第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。
即 q1=m-n
q2=n-q1
...
while q!=0:
if m < n:
m,n = n,m
q = m - n
m = n
n = q<span style="white-space:pre"> </span> max = m<span style="white-space:pre"> </span>
m为最大公约数
算法效率
若计算17 234 500和12 483 721的最小公倍数和最大公约数 1千万与1千万
算法 | 计算时长 |
---|---|
遍历法 | 2640.95ms |
辗转相除法 | 1.47ms |
更相减损法 | 2.40ms |
计算 9 876 543 210和12 345 678的最小公倍数和最大公约数 98亿与1千万
算法 | 计算时长 |
---|---|
遍历法 | 2765.62ms |
辗转相除法 | 2.8135ms |
更相减损法 | 38.82ms |
计算 9 876 543 210和 988 543 214的最小公倍数和最大公约数 98亿与9亿
算法 | 计算时长 |
---|---|
遍历法 | 〉600000ms |
辗转相除法 | 16.97ms |
更相减损法 | 12.95ms |
n个数的最大公约数
求n个数的最大公约数时,可以先求第1、2个数的最大公约数q1,再求q1与第3个数的最大公约数q2,....求q(n-2)与n的最大公约数q(n-1)即可
或者采用2分法对数进行分组,求各个组的最大公约数,q1,q2... q1,q2的最大公约数即为n个数的最大公约数