2017年3月26日 18:47 by wst
数学知识注:本文所有代码均为python2.7实现
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)