1. 程式人生 > >Python實現,求解最小公倍數LCM的方法和效率

Python實現,求解最小公倍數LCM的方法和效率

名詞解釋:

          LCM(least common multiple):最小公倍數

          HCF(highest common factor)or GCD(greatest common divisor):最大公約數

演算法: 

1.暴力法

        較大數除以2個數沒有餘數即得到結果,如果不是,則使最大數自增知道找到結果 

'''
function computeLcm:
input: x y
output: lcm
'''
def computeLcm(x,y):
    if (x > y): 
        greater = x
    else:
        greater = y
    while(True):
        if((greater%x == 0) & (greater%y == 0)):
            lcm = greater
            break
        greater += 1
    return lcm

          這種演算法最簡單,但相對地執行速度比較慢。

基於一個公式

                                                Number1 * Number2 = L.C.M. * G.C.D.

我們通過以下實現這個方法(相同點在於gcd過程使用輾轉相除法,區別在於求gcd的過程是否使用遞迴)

2.遞迴方法

           遞迴的核心是呼叫自身

'''
function RecursiveGcd:
input: x y
output: gcd 
recursive
'''
def RecursiveGcd(x,y):

    if y == 0:
        return x
    else:
        return RecursiveGcd(y, x%y)
'''
function computeLcmWithRecursiveGcd:
input: x y
output: lcm
'''
def computeLcmWithRecursiveGcd(x,y):
    lcm = (x*y)//RecursiveGcd(x,y)
    return lcm

3.非遞迴方法

'''
function NonRecursiveGcd:
input: x y
output: gcd 
non-recursive
'''
def NonRecursiveGcd(x,y):

    while(y):
        x , y = y , x % y
    return x 
'''
function computeLcmWithNonRecursiveGcd:
input: x y
output: lcm
'''
def computeLcmWithNonRecursiveGcd(x,y):
    
    lcm = (x*y)//NonRecursiveGcd(x,y)
    
    return lcm

分析:無論是遞迴法還是非遞迴法,本質都是使用輾轉相除法來求得最大公約數,然後通過兩數相乘處以最大公約數來球的最小公倍數。

分析:遞迴呼叫實際上是函式自己在呼叫自己,而函式的呼叫開銷是很大的,系統要為每次函式呼叫分配儲存空間,並將呼叫點壓棧予以記錄。而在函式呼叫結束後,還要釋放空間,彈棧恢復斷點。所以說,函式呼叫不僅浪費空間,還浪費時間。

部分庫的方法:fractions庫(主要用於分數運算相關)中的gcd方法,我們用ctrl+左鍵檢視函式實現

發現也是非遞迴實現

幾種方法時間消耗測試結果:

從以上的執行結果大致可以證明,效率:非遞迴方法 > 遞迴方法 > 暴力方法

以下附上全部程式碼:

#coding:utf-8
'''
Created on 2018年9月21日

@author: love_paeonia
'''
import time
from fractions import gcd
'''
function computeLcm:
input: x y
output: lcm
'''
def computeLcm(x,y):
    if (x > y): 
        greater = x
    else:
        greater = y
    while(True):
        if((greater%x == 0) & (greater%y == 0)):
            lcm = greater
            break
        greater += 1
    return lcm


'''
function RecursiveGcd:
input: x y
output: gcd 
recursive
'''
def RecursiveGcd(x,y):

    if y == 0:
        return x
    else:
        return RecursiveGcd(y, x%y)



'''
function computeLcmWithRecursiveGcd:
input: x y
output: lcm
'''
def computeLcmWithRecursiveGcd(x,y):
    lcm = (x*y)//RecursiveGcd(x,y)
    return lcm



'''
function NonRecursiveGcd:
input: x y
output: gcd 
non-recursive
'''
def NonRecursiveGcd(x,y):

    while(y):
        x , y = y , x % y
    return x 



'''
function computeLcmWithNonRecursiveGcd:
input: x y
output: lcm
'''
def computeLcmWithNonRecursiveGcd(x,y):
    
    lcm = (x*y)//NonRecursiveGcd(x,y)
    
    return lcm


if __name__ == '__main__':
    
    start1 = time.clock()
    computeLcm(7, 131)
    print "function computeLcm time cost: " + (time.clock() - start1).__str__()
    
    start2 = time.clock()
    computeLcmWithRecursiveGcd(7, 131)
    print "function computeLcmWithRecursiveGcd time cost: " + (time.clock() - start2).__str__()
     
    start3 = time.clock()
    computeLcmWithNonRecursiveGcd(7, 131)
    print "function computeLcmWithNonRecursiveGcd time cost: " + (time.clock() - start3).__str__()
    
    start4 = time.clock()
    gcd(7, 131)
    print "function fractions.gcd time cost: " + (time.clock() - start4).__str__()