欧几里得扩展算法

欧几里得扩展算法

首先证明欧几里德算法(即最大公约数算法)

设有a,b两个数;

a=k*b+r,r=a%b;

假设d是a,b的一个公约数,a%d=0,b%d=0;r=a-k*b,因此r%d=0;

即所有a,b的公约数都是b,a%b的公约数,那么gcd(a,b)=gcd(b,a%b);

所以当a%b=0时,即a和b的最大公约数就是他们本身;


算法代码

int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
gcd(a,b)=gcd(b,r0)=gcd(r0,r1)=...=gcd(rn-1,rn)=gcd(rn-1,0)=rn-1.


接下来讲解欧几里得扩展算法(即求n*a+m*b=gcd(a,b)中的n,m)

首先m*a+n*b=gcd(a,b);

当a=k*b+r;r=0时,m=0,n=1;

当r!=0时,有上述可知m*(k*b+r)+n*b=gcd(a,b)=gcd(b,r);

假设m1*b+n1*r=gcd(b,r);

b=k1*r+r1;当r1=0时,则m1,n1已知;

代入上式 得

m1*b+n1*r=m*(k*b+r)+n*b;

m1*b+n1*r=(m*k+n)*b+m*r;

得 m=n1,n=m1-m*k=m1-n1*a/b;

由于代码中用了引用所以是y-=x*(a/b),仔细理解一下;

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

最后总结:

关于欧几里得算法用于求解整数问题和最大公约数(白书179);

虽然可以求出一组解但是本质上是有许多解的,比如已知(x,y),所有解为(x+k*b/gcd(a,b),y-k*a/gcd(a,b));

原文地址:https://www.cnblogs.com/zhangteng512/p/2090924.html