扩展欧几里得算法用于:
1.求不定方程
2.求解模的逆元
1.求不定方程
2.求解模的逆元
3.求解同余方程
/*
* 扩展欧几里得算法(extended Euclidean algorithm)
* 扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式:
* ax+by = gcd(a, b) = d(解一定存在,根据数论中的相关定理)。
* 扩展欧几里德常用在求解模线性方程及方程组中。
*
*/
#include <stdio.h>
// 递归法实现扩展欧几里德算法
long exgcd1(long a, long b, long *x, long *y)
{
if(b==0) {
*x=1;
*y=0;
return a;
}
long r = exgcd1(b, a%b, x, y);
long t = *x;
*x = *y;
*y = t - a / b * *y;
return r;
}
// 递推法实现扩展欧几里德算法(正解)
long exgcd2(long a, long b, long *x, long *y)
{
long x0=1, y0=0, x1=0, y1=1;
long r, q;
*x=0;
*y=1;
r = a % b;
q = (a - r) / b;
while(r)
{
*x = x0 - q * x1;
*y = y0 - q * y1;
x0 = x1;
y0 = y1;
x1 = *x;
y1 = *y;
a = b;
b = r;
r = a % b;
q = (a - r) / b;
}
return b;
}
int main(void)
{
long x, y;
printf("a=%d, b=%d, x=%ld, y=%ld exgcd=%ld\n", 42, 70, x, y, exgcd1(42, 70, &x, &y));
printf("a=%d, b=%d, x=%ld, y=%ld exgcd=%ld\n", 42, 70, x, y, exgcd2(42, 70, &x, &y));
return 0;
}
关键代码(正解):
// 递推法实现扩展欧几里德算法(正解)
long exgcd2(long a, long b, long *x, long *y)
{
long x0=1, y0=0, x1=0, y1=1;
long r, q;
*x=0;
*y=1;
r = a % b;
q = (a - r) / b;
while(r)
{
*x = x0 - q * x1;
*y = y0 - q * y1;
x0 = x1;
y0 = y1;
x1 = *x;
y1 = *y;
a = b;
b = r;
r = a % b;
q = (a - r) / b;
}
return b;
}