我的个人博客:地址
欧几里得算法计算的是两个自然数a和b的最大公约数,两个数的最大公约数通常写成gcd(a, b),如果有gcd(a, b)==1,则有a,b互质。
欧几里得算法
- 递归
int Gcd(int a, int b)
{
if(b == 0)
return a;
return Gcd(b, a % b);
}
- 迭代
int Gcd(int a, int b)
{
while(b != 0)
{
int r = b;
b = a % b;
a = r;
}
return a;
}
扩展欧几里得算法
介绍
扩展欧几里德算法是用来在已知a, b求解一组p,q使得p*a+q*b=Gcd(a,b)(根据数论中的相关定理解一定存在,不展开叙述)。扩展欧几里德常用在求解模线性方程及方程组中。算法
int exGcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int r = exGcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;
}
- 理解
把这个实现和Gcd的递归实现相比,发现多了下面的x,y赋值过程,这就是扩展欧几里德算法的精髓。 可以这样思考: 对于a’ =b , b’ =a%b 而言,我们求得x, y使得a’ x+b’ y=Gcd(a’, b’) 由于b’ = a % b = a - a / b * b 那么可以得到 :
a’ x + b’ y = Gcd(a’ , b’)
===>
bx + (a - a/b *b)y = Gcd(a’ , b’) = Gcd(a, b) //注意到这里的/是C语言中的出发
===>
ay + b(x- a/b *y) = Gcd(a, b)
因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y)