通过本文,我们将发现欧几里得算法(求两个数的最大公约数,也称作辗转相除),根本不需要死记硬背,仅仅通过数论中的一个小小的结论(有关可公度线段,commensurable),即可轻易推导出来。
既然算法来自欧几里得两千年前的几何原本
一书,我们也回归代数与几何在书中含义上的统一,继续沿用书中的说法。假如我们要求线段
a
和线段
如果 b 正好能度量
a ( b 能度量a 的含义是 a 是b 的整数倍), b 自然也能度量它自身,因此b 就是 a 和b 的一个公度单位;如果 b 不能被
a 整除,这说明 a 的长度等于b 的某个整数倍,再加上一个零头(余数),不妨把该零头记为 c ,也即此时a=k⋅b+c 。如果此时某条线段能同时度量 b 和c ,那么它显然也能度量 a 。也即,此时为了找到a 和 b 的共度单位,我们只需寻找b 和 c 的公度单位即可。此时便构成了递归;
def euclid(a, b):
if a < b:
a, b = b, a
return b if a % b == 0 else euclid(b, a%b)
证明
我们不妨把 Euclid 算法对
效率
欧几里得算法(辗转相除法)的效率其实非常高。实际上,我们可大致估计出辗转相除的效率。第一次做除法时,我们 amodb=c ,
如果 b 的值不超过
a 的一半,那么 c 更不会超过a 的一半(因为余数小于除数)。如果 b 的值超过了
a 的一半,那么 c 直接就等于a−b ( a=k⋅b+c ,此时 k 只能为1),同样小于a 的一半;
也即辗转相除法的运算次数是对数级别的;