您的位置:首页 > 其它

求最大公约数和最小公倍数的三个算法

2017-08-07 14:56 531 查看
摘要:分别定义了三种求最大公约数和最小公倍数的函数:遍历法,辗转相除法,更相减损法(辗转相除法是最好的算法);time模块的clock()方法,用来测算程序执行所消耗的时间。

遍历法

遍历法的可以从前往后遍历,也可以从后往前遍历。简单来说就是判断一个数是否都是研究对象m和n的约数。

代码:

from time import clock  #从time模块导入clock()方法
def GCDivisor(m,n):     #Greatest common divisor 最大公约数
if cmp(m,n) is 1:   #如果m>n,cmp(m,n)会返回1,相等返回0,m<n返回1
m,n=n,m         #把m,n从小到大排列,则不再需要额外的min
aList=range(1,m)[::-1]  #从后往前找的方法
for i in aList:
if m%i==0 and n%i==0:
break           #从后往前找可以直接找到最大的公约数,然后停止循环
return i

# aList=range(1,m)      #从前往后找的方法
# for i in aList:
#     if m%i==0 and n%i==0:
#         max=i         #从前往后找,每找到一个公约数就更新最大公约数
# return max

def LCMultiple(m,n):    #Least common multiple  最小公倍数
i=int(GCDivisor(m,n))
return m*n/i        #LCM=(m/i)*(n/i)*i=m*n/i  #最小公倍数的计算公式

clock1=clock()  #时间点1
m=1234;n=4321
print '最大公约数:',GCDivisor(m,n)
clock2=clock()   #时间点二
print '耗时'+str((clock2-clock1)*1000)+'ms' 


辗转相除法

辗转相除法是三个方法中最好的算法,处理较大的整数时尤为明显。基本过程是:研究对象(假设m>n)m%n的余数为q,则较小的n与q的最大公约数,是m与n的最大公约数。递推下去,直到n%q=0,此时的n为最大公约数。

代码:

from time import clock  #从time模块导入clock()方法

#辗转相除法:两数中的最小数,和两数相除所得的余数的最大公约数,为两数的最大公约数
def ZZDivisor(m,n):
if cmp(m,n) is 1:
m,n=n,m     #m小n大
q=1
while q!=0:
q=n%m       #q为两数余数
n=m         #m比余数大,让m成为被除数
m=q         #余数小,做除数
#一直循环到余数为零,此时被除数n是最大公约数
return n

clock1=clock()
m=9876543210;n=988543214
print '最大公约数:',ZZDivisor(m,n)
clock2=clock()
print '耗时'+str((clock2-clock1)*1000)+'ms'


更相减损法

见代码:

from time import clock  #从time模块导入clock()方法

#更相减损法:先判断两数是否同时为偶数,是则都除2,直到不是偶数;
#两数相减得差,用小数与差相减得差,再次用小数与差相减...直到所得差为0
#最大公约数等于差为0的数值乘上约掉的若干个2
def JSDivisor(m,n):
i=0
while m%2==0 and n%2==0:
m/=2
n/=2
i+=1    #记录约掉了多少次2
q=1
if cmp(m,n) is 1:
m,n=n,m     #m小n大,下面while循环中的cmp(m,p)也是为了保证m小n大
while q!=0:
q=n-m
if cmp(m,q) is 1:   #最后一步,q=0,m比q大
m,n=q,m     #最后一步,m=q=0,值在n上
else:
m,n=m,q

return  n*(2**i)

clock1=clock()
m=9876543210;n=988543214
print '最大公约数:',JSDivisor(m,n)
clock2=clock()
print '耗时'+str((clock2-clock1)*1000)+'ms'

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: