求解两个正整数的最大公约数(Greatest Common Devisor),可以采用循环进行遍历,不过效率很低。所以引入欧几里得算法(Euclid’s algorithm)。
欧几里得算法基于GCD递归引理:
对任意非负整数a和任意正整数b,
gcd(a, b) = gcd(b, a mod b)
可以直接写出递归程序:
int GCD(int a, int b)
{
if(0 == b)
return a;
else
return GCD(b, a % b);
}
- 复杂度分析
运行时间与递归调用的次数成正比。
时间复杂度O(lgb)O(lgb),最坏情况下计算次数N≤5log10bN≤5log10b。
证明:欧几里得算法
- 扩展欧几里得算法
可以计算出满足下式的三元组(d,x,y)(d,x,y):
d=GCD(a,b)=ax+byd=GCD(a,b)=ax+by
int Euclid_extend(int a, int b, int* x, int* y)
{
if(0 == b)
{
*x = 1;
*y = 0;
return a;
}
else
{
int r = Euclid_extend(b,a%b,x,y);
int temp = *x;
*x = *y;
*y = temp - (*y)*(a/b);
return r;
}
}
简单证明:
b=0b=0是递归基,易得一组解x=1,y=0x=1,y=0;
b≠0b≠0时:
首先递归求解:
d′=gcd(b,a%b)=bx′+(a%b)y′ (1)d′=gcd(b,a%b)=bx′+(a%b)y′ (1)
我们知道:
d=gcd(a,b)=d′=gcd(b,a%b) (2)d=gcd(a,b)=d′=gcd(b,a%b) (2)
a%b=a−b∗⌊a/b⌋ (3)a%b=a−b∗⌊a/b⌋ (3)
将(2)(3)式带入(1):
d=bx′+(a−b⌊a/b⌋)y′=ay′+b(x′−⌊a/b⌋y′)d=bx′+(a−b⌊a/b⌋)y′=ay′+b(x′−⌊a/b⌋y′)
所以,令 x=y′x=y′、 y=x′−⌊a/b⌋y′y=x′−⌊a/b⌋y′,就可以满足 d=ax+byd=ax+by。