最大公约数

两个正整数r0和r1的最大公约数表示为:
他指的是被r0和r1同时整除的最大正整数,例如:

欧几里得算法

定义

在数学中,辗转相除法,又称欧几里得算法(英语:Euclidean algorithm),是求最大公约数的算法。

证明

补充说明

  • 上述r0 = g*x,r1 = g*y; 如果x和y不互素,r0和r1的公约数就不是g,而是g*d(d为x和y的公约数)
  • 如果x-y和x不互素,根据反证法得:

    扩展定义

根据欧几里得定义可得:

只要r0-mr1>0,上述等式依然成立,为了减少计算步骤,每次都可以取使得r0-mr1>0成立的最大的m的值来计算,此时r0-mr1=r0 mod r1,所以欧几里得定理也可以表示为:

案例

实现

1
2
3
4
5
def gcd(a, b):
    while a != 0:
        a, b = b % a, a

    return b

扩展欧几里得算法

定义

已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,找到整数x、y(其中一个可能是负数),使它们满足貝祖等式:ax+by=gcd(a,b)

原理

递归原理

非递归原理

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 递归的实现方式,利用Xn和Yn的关系正向推导
def ext_euclid(a, b):    
    if b == 0:        
        return 1, 0, a    
    else:        
        # q = gcd(a, b) = gcd(b, a%b)
        x, y, q = ext_euclid(b, a % b)
        x, y = y, (x - (a // b) * y)
        # x*a + y*b = gcd(a,b) = q
        return x, y, q


# 参考资料:
# https://zh.wikipedia.org/zh/%E6%89%A9%E5%B1%95%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E7%AE%97%E6%B3%95
# https://oi-wiki.org/math/number-theory/gcd/#%E6%89%A9%E5%B1%95%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E7%AE%97%E6%B3%95
# 非递归的实现方式
def ext_euclid(a, b):
    old_x, x = 1, 0
    old_y, y = 0, 1
    old_r, r = a, b
    if b == 0:
# 可省略
        return 1, 0, a
    else:
        while(r!=0):
            q = old_r // r
            old_r, r = r, old_r-q*r
            old_x, x = x, old_x-q*x
            old_y, y = y, old_y-q*y
    # old_x*a + old_y*b = gcd(a,b) = old_r
    return old_x, old_y, old_r