辗转相除法(欧几里得算法)和扩展欧几里得算法实现及证明

辗转相除法(欧几里得算法)和扩展欧几里得算法实现及证明

今天看了好长时间的数论知识点,学完之后,过了一个假期,再回头看扩展欧几里得时已经是

懵 懵 懵

于是我上网找到了它的证明

(叙述的可能会非常啰嗦详细)


辗转相除法:

定义及用途:

辗转相除法, 又名欧几里德算法,是求最大公约数的一种方法。它的具体做法是:用较小数除较大数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
——摘自百度百科

证明:

我们想要证明 a a b b 的最大公约数和 b b a mod b a   m o d   b 的最大公约数相等,即 gcd(a,b)=gcd(b,a mod b) g c d ( a , b ) = g c d ( b , a   m o d   b )

可以令 a=kb+r a = k b + r ,则 r=akb r = a − k b ,其中 k=a/b k = ⌊ a / b ⌋ ,( x ⌊ x ⌋ 表示向下取整),那么 r=a mod b r = a   m o d   b

  • a a , b b 的一个公约数为 d d ,则 a a b b 都可以被 d d 整除,同时 r r 也可被 d d 整除(这里可以自己想一下)。所以 d d b b a mod b a   m o d   b 的公约数。

  • b b a mod b a   m o d   b 的一个公约数为 d d ,则 b b , r r 可以被 d d 整除,同时 a=kb+r a = k b + r ,所以 d d 也是 a a b b 的公约数。

综上, a,b a , b b,a mod b b , a   m o d   b 的公约数是一样的,其最大公约数也必然相等。

实现:

辗转相除法是我们很早的时候就了解的算法,实现也有很多种方法,可以用递归或非递归的方式实现,这里就不再给出


扩展欧几里得算法:

定义及用途:

就是对欧几里得算法的扩展

扩展欧几里得算法可以用来求解线性同余方程和乘法的逆元。

线性同余方程的解法步骤这里就不再赘述,扩展欧几里得算法所能实现的就是:给定 a a b b ,求解 x x , u u ,使之满足 ax+by=gcd(a,b)=d a x + b y = g c d ( a , b ) = d 。接下来给出过程及证明

证明:

已知: ax+by=1 a x + b y = 1 a a b b 互质

求: x x y y

ax+by=1=gcd(a,b) a x + b y = 1 = g c d ( a , b )

根据朴素的辗转相除法得: gcd(a,b)=gcd(b,a mod b) g c d ( a , b ) = g c d ( b , a   m o d   b )

所以: ax+by=gcd(b,a mod b)=bx1+(a mod b)y1 a x + b y = g c d ( b , a   m o d   b ) = b x 1 + ( a   m o d   b ) y 1

又因为: a mod b=aa/bb a   m o d   b = a − ⌊ a / b ⌋ ∗ b

所以展开并移项得:

ax+by=bx1+(aa/bb)y1 a x + b y = b x 1 + ( a − ⌊ a / b ⌋ ∗ b ) y 1

ax+by=bx1+ay1ba/by1 a x + b y = b x 1 + a y 1 − b ∗ ⌊ a / b ⌋ y 1

ax+by=ay1+b(x1a/by1) a x + b y = a y 1 + b ( x 1 − ⌊ a / b ⌋ ∗ y 1 )

所以: x=y1 x = y 1 , y=x1a/by1 y = x 1 − ⌊ a / b ⌋ ∗ y 1 ,这就是 x x y y x1 x 1 y1 y 1 的关系

像这样递归下去,直到 b=0 b = 0 ,此时 anxn+0yn=gcd(an,0)=an a n x n + 0 ∗ y n = g c d ( a n , 0 ) = a n ,那么 xn=1 x n = 1 , yn= y n = 任 意 数 ,为了方便,我们取 y=0 y = 0 .

之后进行回溯, x=y1 x = y 1 , y=x1a/by1 y = x 1 − ⌊ a / b ⌋ ∗ y 1 ,最后就做到了在求解 a a b b 的最大公约数的过程中也实现了对 x x y y 的求解,这也是这个算法叫做扩展欧几里得的原因。

实现:

网上扩展欧几里得算法的模板很多,这里给出一个:

int exgcd(int a,int b)
{
    if(b==0)//边界
    {
        x=1;
        y=0;//y可以为任意数,这里取0
        return a;
    }
    int r=exgcd(b,a%b);
    int t=x;
    x=y;//更新解的过程
    y=t-a/b*y;//更新解的过程
    return r;
}

其他:

这里再推荐两个博客,也是有关证明的,可以看一下

https://blog.csdn.net/lincifer/article/details/49391175

http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html


结束了。

有不严谨的地方还请指正。

你可能感兴趣的:(辗转相除法(欧几里得算法)和扩展欧几里得算法实现及证明)