描述
说明
- 欧几里得算法又称辗转相除法,可用于求两个正整数的最大公约数
示例
a = 30,b = 18,求a与b的最大公约数a % b = 12=>a = 18,b = 12a % b = 6=>a = 12,b = 6a % b = 0=> 此时的b即为原来两数的最大公约数
补充
a不必大于b,因为取模操作可以将大的数提前
要求
- 写出“欧几里德算法”的程序,起名为
gcd() gcd为Greatest Common Divisor的缩写
程序
def gcd(num1, num2):
while num2 != 0:
num1, num2 = num2, num1 % num2
return num1
证明
证法一
设 num1, num2, m, r, d 均为自然数
不妨设 num1 > num2,d 为两个数的任意一个公约数 且 num1 / num2 = m ...... r
=> r = num1 - m * num2 => r/d = (num1 - m * num2)/d = num1/d - m*num2/d
因为 d 为 num1, num2 的公约数,且 m 为自然数,所以 r/d 也是自然数
=> d 必是 r 的约数
=> 求 num1 与 num2 的最大公约数,可以转为求 num2 与 r 的最大公约数
证法二
step1 证明 d 是 r 的约数
令 d 为 num1, num2 的最大公约数
取 num1 的某一个约数 m1, num2 的某一个约数 m2,使得 num1 = m1 * d, num2 = m2 * d —— (1)
不妨设 r = num1 % num2 = num1 - m * num2 —— (2)
将 (1) 代入 (2),得 r = m1 * d - m * (m2 * d) = (m1 - m * m2) * d
=> d 是 r 的约数
step2 证明 m1-m*m2 与 m2 互质
若 (m1 - m * m2) 与 m2 不互质
不妨设 (m1 - m * m2) = k1 * d', m2 = k2 * d', (d'>1)
m1 = m * m2 + k1 * d' = m * (k2 * d') + k1 * d' = (m * k2 + k1) * d'
=> num1 = m1 * d = [(m * k2 + k1) * d'] * d = (m * k2 + k1) * (d' * d),
num2 = m2 * d = (k2 * d') * d = k2 * (d' * d)
=> num1 与 num2 有公约数 (d' * d)
因为 d' > 1, d >= 1,所以 (d' * d) > d
=> 与开头题设矛盾
=> (m1 - m * m2) 与 m2 互质
=> d 也是 r 与 num2 的最大公约数