最大公约数

来源:互联网 发布:qq刷留言板软件 编辑:程序博客网 时间:2024/06/15 15:15

最大公约数

本部分主要是欧几里得算法与拓展欧几里得算法。

欧几里得算法

定理(GCD递归定理):对任意非负整数a和任意正整数b, gcd(a,b) = gcd(b , a mod b) .

证明:要证明gcd(a,b)与gcd(b , a mod b)相等即证明两者可以互相整除。 首先证明gcd(a,b) | gcd(b , a mod b),设d = gcd(a,b),则d | a,d | b。因为(a mod b) = a - qb,其中q = ⌊a/b⌋。因为a mod b是a与b的线性组合,所以由4#可得d | (a mod b)。因为d | b且 d|(a mod b),再次由4#可得,d | gcd(b,a mod b), 即等价于 gcd(a,b) | gcd(b , a mod b)。
其次证明gcd(b , a mod b) | gcd(a , b),其方法与上述过程类似,设d = gcd(b , a mod b),则 d | b,d | (a mod b)。因为 a = qd + (a mod b),其中q = ⌊a/b⌋。所以a是b和(a mod b)的一个线性组合,所以由4#可知, d | a。 因为 d | a, d | b,所以d | gcd(a,b)。即 gcd(b , a mod b) | gcd( a , b)。

综上:因为gcd(a,b) | gcd( b , a mod b)且gcd(b , a mod b) | gcd(a , b),所以gcd(a , b) = gcd(b , a mod b)。

从以上定理我们可以很容易的写出gcd函数,如下(c++版):

    int gcd(int a,int b){        return b == 0 ? a : gcd(b , a % b);    }

拓展欧几里得算法

先上代码再证明其正确性(c++版):

    void Extended_gcd(int a,int b,int &d,int &x,int &y){        if(b == 0){            d = a; x = 1;  y = 0;        }         else {            Extended_gcd(b,a % b,d,y,x);            y -= x*(a/b);        }

证明:如果b = 0,则Extended_gcd不仅返回d = a,而且返回系数x = 1和y = 0,使得 a = ax + by。如果 b != 0,则Extended_gcd首先计算出满足d’ = gcd(b , a mod b)和 d’ = bx’ + (a mod b)y’的x’与y’。在这种情况下,有 d = gcd(a,b) = d’ = gcd(b,a mod b)。为了得到满足 d = ax + by的x与y,则d = bx’ + (a - b⌊a/b⌋y’) = ay’ + b(x’-⌊a/b⌋y’),所以当x = y’,y = x’ - ⌊a/b⌋y’时,满足d = ax + by。故此算法正确。

原创粉丝点击