知乎偶遇dalao。感觉解释的很好理解,故转载。
原帖链接:https://www.zhihu.com/question/30067108/answer/153440477
对于正整数(纠正,不是非负整数) a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得
a*x+b*y = gcd(a , b); ①
根据欧几里德原理gcd(a , b) = gcd(b , a mod b)
将gcd(b,a mod b)表达为①式的形式,即
a*x+b*y = gcd(a , b)
= gcd(b , a mod b)
= b * x1 + (a mod b) * y1
= b * x1 + (a - a / b * b) * y1
即ax+by = b * x1 + (a - a / b * b) * y1
化简上式,得
a*x+b*y = a*y1 - b*a/b*y1 + b*x1
即
a * x + b * y= a * y1 + b * (x1-a/b*y1)
所以x=y1y=x1 - a/b*y1
于是我们得到了这样一段代码
void exgcd(int a, int b, int &d, int &x ,int &y)
{
if ( !b )
{
d = a;
x = 1;
y = 0;
return;
}
int x1,y1;
exgcd( b , a % b , d , x1 , y1 );
x = y1;
y = x1 - ( a / b ) * y1;
return ;
}
有了推理过程,这段代码比题主的那一段要更加好理解但是细想其实等价于题主的代码,只是在传递参数的时候交换了 x 和 y 的位置
void exgcd(int a, int b, int &d, int &x,int &y)
{
if(!b)
{
d = a;
x = 1;
y = 0;
return;
}
exgcd(b , a%b , d , y , x);
y-=a/b*x;
}