在《看数据结构与算法分析》一书时,看到了求最大公因数(Gcd)的算法——欧几里德算法,查询资料了解到此算法的原理如下:
首先,该算法依赖一个重要的定理:gcd (a,b) = gcd ( b, a mod b)。此方法证明如下:
a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a,d|b,而r = a - kb,因此d|r
因此d也是(b,a mod b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
因此在求a,b的最大公约数时,采用上述定理可以将其转化为b与a mod b的最大公约数问题,使问题得到了简化,由于Gcd(a,b)=Gcd(-a,b),因此只考虑正整数的问题。
欧几里德算法采用辗转相除的方法,具体过程如下:
a = b * h0 + r0,其中r0 < b;
若r0 > 0,则有 b = r0 * h1 + r1,其中r1 < r0;
若r1 > 0,则有 r0 = r1 * h2 + r2,其中r2 < r1;
即gcd(a,b) = gcd(b,r0) = gcd(r0,r1) = ... = gcd(rn - 1,rn)
如此继续下去,直到rn = 0 为止,当rn = 0时,则有
gcd(rn - 2,rn - 1) = gcd(rn - 1,rn),即rn - 2 = rn - 1 * hn + rn,其中rn = 0,所以 rn - 2 = rn -1 * hn,因此rn - 2 % rn - 1 = 0
即gcd(rn-2,rn-1)=rn-1,因此gcd(a,b)=rn -1
下面写C语言实现过程:
unsigned int Gcd(unsigned int M,unsigned int N) {
unsigned int Rem;
while ( N > 0) {
Rem = M % N;
M = N;
N = Rem;
}
return M;
}