ex08 欧几里德算法

描述

说明

  • 欧几里得算法又称辗转相除法,可用于求两个正整数的最大公约数

示例

  • a = 30, b = 18,求 ab 的最大公约数
    1. a % b = 12 => a = 18, b = 12
    2. a % b = 6 => a = 12, b = 6
    3. a % b = 0 => 此时的 b 即为原来两数的最大公约数

补充

  • a 不必大于 b,因为取模操作可以将大的数提前

要求

  • 写出“欧几里德算法”的程序,起名为 gcd()
  • gcdGreatest Common Divisor 的缩写

程序

def gcd(num1, num2):
    while num2 != 0:
        num1, num2 = num2, num1 % num2
    return num1

证明

证法一

num1, num2, m, r, d 均为自然数

不妨设 num1 > num2d 为两个数的任意一个公约数 且 num1 / num2 = m ...... r

=> r = num1 - m * num2 => r/d = (num1 - m * num2)/d = num1/d - m*num2/d

因为 dnum1, num2 的公约数,且 m 为自然数,所以 r/d 也是自然数

=> d 必是 r 的约数

=> 求 num1num2 的最大公约数,可以转为求 num2r 的最大公约数

证法二

step1 证明 d 是 r 的约数

dnum1, 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

=> dr 的约数

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)

=> num1num2 有公约数 (d' * d)

因为 d' > 1, d >= 1,所以 (d' * d) > d

=> 与开头题设矛盾

=> (m1 - m * m2)m2 互质

=> d 也是 rnum2 的最大公约数

原文地址:https://www.cnblogs.com/yorkyu/p/10367428.html