辗转相除法、更相减损术求最大公约数的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