輾轉相除法、更相減損術求最大公約數的python實現


輾轉相除法

簡單證明輾轉相除法的原理

1.解析:
8251=6105+2146,為了表示簡單,我就用a=b+c表示這個吧
於是有c=a-b
那么如果有d|a,且d|b,就必然有d|a-b,也就是d|c,
(d|a表示:d為a的約數)
可見a和b的公約數必然也是c的約數.
現在假設d是a和b的最大公約數,那么d也必然是c的約數,於是d是b,c的公約數,現在就要證明它是最大公約數:

2.證明:
因為a=b+c,於是b,c的公約數也必然是a的約數,假設(b,c)=e,
((b,c)=e表示e為b和c的最大公約數)那么有e|b+c,即e|a
根據"d是b,c的公約數"知道d|e,,
又因為e也是a,b的公約數,e|d,綜上有e=d
可見(a,b)=(b,c)=d

(這個思想一推廣,就成了輾轉相除法了)

3.實現

def euclidean_algorithm(a,b):
    """輾轉相除法求最大公約數"""
    if a < b:
        a, b = b, a
    r = 1
    while r != 0:
        r = a % b
        a = b
        b = r
    return a

 

《九章算術》更相減損術

思想

九章算術》是中國古代的數學專著,其中的“更相減損術”可以用來求兩個數的 最大公約數,原文是:
 
可半者半之,不可半者,副置分母、子之數,以少減多,更相減損,求其等也。以等數約之。

 

 
白話文譯文:
(如果需要對分數進行約分,那么)可以折半的話,就折半(也就是用2來約分)。如果不可以折半的話,那么就比較分母和分子的大小,用大數減去小數,互相減來減去,一直到減數與差相等為止,用這個相等的數字來約分。

使用步驟

第一步:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步。
第二步:以較大的數減較小的數,接着把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。
則第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。
其中所說的“等數”,就是 最大公約數。求“等數”的辦法是“更相減損”法。

實現

def gengxianjiansun(a, b):
    """《九章算術》中的“更相減損術”"""
    if a < b:
        a, b = b, a
    # 初始化差的集合為空
    divisors = []
    # 初始化最大公約數為1
    num = 1

    # 第一步:判斷是否都是偶數
    if a % 2 == 0 and b % 2 == 0:
        a, b = a/2, b/2
        num *= 2

    # 第二步:更替相減
    r = a - b
    while r not in divisors:
        divisors.append(r)
        a = max(b, r)
        b = min(b, r)
        r = a - b
    return num * r

附完整代碼

# -*- coding:utf-8 -*-


def euclidean_algorithm(a,b):
    """輾轉相除法求最大公約數"""
    if a < b:
        a, b = b, a
    r = 1
    while r != 0:
        r = a % b
        a = b
        b = r
    return a


def gengxianjiansun(a, b):
    """《九章算術》中的“更相減損術”"""
    if a < b:
        a, b = b, a
    # 初始化差的集合為空
    divisors = []
    # 初始化最大公約數為1
    num = 1

    # 第一步:判斷是否都是偶數
    if a % 2 == 0 and b % 2 == 0:
        a, b = a/2, b/2
        num *= 2

    # 第二步:更替相減
    r = a - b
    while r not in divisors:
        divisors.append(r)
        a = max(b, r)
        b = min(b, r)
        r = a - b
    return num * r

if __name__ == "__main__":
    print euclidean_algorithm(8,9)
    print gengxianjiansun(8,20)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM