求兩個數字的最大公約數-Python實現,三種方法效率比較,包含質數打印質數的方法

今天面試,遇到面試官詢求最大公約數。小學就學過的奧數題,竟然忘了!只好回答分解質因數再求解!面試

回來果斷複習下,經常使用方法展轉相除法更相減損法小學奧數都學過,很簡單,就不細說了,忘了的話能夠百度:http://baike.baidu.com/link?url=Ba106RbHkMjZm3rolmCHEEFt3eDkVbngcReykcqt4Wv0dbTI_0ZmTDE5b0X-xWFxapp

如下是代碼實現,這兩種方法,還有常規的分解因式,順便比較了一下效率,其中分解因式用了兩種方法來求取小於該數字的全部質數,:測試

 

#coding:utf-8
import time
#展轉相除法:
def commonDivisor1(num1,num2):
    if num1 < num2:
        temp = num1
        num1 = num2
        num2 = temp
         
    if  num1%num2 ==0:
        return num2
    else:
        num2 = num1%num2
        return commonDivisor1(num1,num2)

#更相減損法
def commonDivisor2(num1,num2):    
    if num1==num2:return num1
    elif num1 < num2:
        temp = num1
        num1 = num2
        num2 = temp
    if num1 - num2 == num2:
        return num2
    else:
        temp = num1 
        num1 = num2
        num2 = temp - num2
        #print (num1,' ', num2)
        return commonDivisor2(num1,num2)

#分解質因數,以後求解
def commonDivisor3(num1,num2):
    if num1==num2:return num1
    elif num1 < num2:
        temp = num1
        num1 = num2
        num2 = temp  
    #求小於較小數字的全部素數   
    primeNum = getPrimeNumber1(num2)
    #print (primeNum)
    #對較小的數字分解質因數,並將質因數保存在l2中
    l2 = []
    result = 1 
    while num2 != 1:
        for i in primeNum:
            if num2 % i !=0:
                continue
            else:
                l2.append(i)
                num2 = num2 / i 
    #print ('l2: ',l2)
    #使用較大數字去除較小數字的質因數,看大數字中包含了哪些較小數字的質因數。
    #將大數字也包含的相同的質因數相乘返回結果,即最大公約數
    for i in l2:
        if num1 % i == 0:
            result = result*i
            num1 = num1/i
    return result

#分解質因數,以後求解
def commonDivisor4(num1,num2):
    if num1==num2:return num1
    elif num1 < num2:
        temp = num1
        num1 = num2
        num2 = temp  
    #求小於較小數字的全部素數   
    primeNum = getPrimeNumber2(num2)
    #print (primeNum)
    #對較小的數字分解質因數,並將質因數保存在l2中
    l2 = []
    result = 1 
    while num2 != 1:
        for i in primeNum:
            if num2 % i !=0:
                continue
            else:
                l2.append(i)
                num2 = num2 / i 
    #print ('l2: ',l2)
    #使用較大數字去除較小數字的質因數,看大數字中包含了哪些較小數字的質因數。
    #將大數字也包含的相同的質因數相乘返回結果,即最大公約數
    for i in l2:
        if num1 % i == 0:
            result = result*i
            num1 = num1/i
    return result

#列出小於num的全部奇數,首先去除能夠被2整除的,再去除能夠被3整除的,再去除能夠被5整除的,以此類推...           
def getPrimeNumber1(num):
    l = [2]
    for i in range(3,num+1,2):
        l.append(i)
    j = min(l)
    while not j == l[-1]:
        for k in l:
            if (k%j==0) and k != j:
                #print ('remove: ',k)
                l.remove(k)
        #print (l,' ',j)
        j = l[l.index(j)+1]
    return l

#用生成器和filter求num之內的全部質數
def getPrimeNumber2(num):
    l=[]
    for n in primes():
        if n < num:
            l.append(n)
        else:
            break
    return l

#建立打印奇數的生成器
def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n

#建立過濾條件,即過濾掉能夠被列表中下一個數字整除的數字,留下不能夠被這個數整除的,即留下質數
def _not_divisible(n):
    return lambda x: x % n > 0

#不斷迭代生成列表,根據規則過濾掉列表中元素,留下質數
def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一個數
        yield n
        it = filter(_not_divisible(n), it) # 構造新序列
  
time1 = time.clock()
print (commonDivisor1(12355,525))
time2 = time.clock()
print (commonDivisor2(12355,525))
time3 = time.clock()
print (commonDivisor3(12355,525))
time4 = time.clock()
print (commonDivisor4(12355,525))
time5 = time.clock()

print ('展轉相除法用時: ', (time2-time1)*1000,'')
print ('更相減損法用時: ', (time3-time2)*1000,'')
print ('分解質因數法用時(用列表求質數): ', (time4-time3)*1000,'')
print ('分解質因數法用時(用生成器求質數): ', (time5-time4)*1000,'')

 

 

 

 測試結果:url

隨便測試兩個數字,發現展轉相除法明顯是最快的,緣由也很明顯,計算次數明顯比更相減損法少,傳統分解因式方法,那效率天然不用說了。spa

35353535展轉相除法用時:  0.014617272401167485 秒更相減損法用時:  0.15565419800162134 秒分解質因數法用時(用列表求質數):  9.131449575150953 秒分解質因數法用時(用生成器求質數):  8.505277230398239 秒
相關文章
相關標籤/搜索