问题
求两正整数a和b的最大公约数(GreatestCommonDivisor)和最小公倍数(LeastCommonMultiple)。
解法
设gcd(a,b)表示非负整数a,b的最大公约数,任意正整数a和b满足:
gcd(a,b)={bgcd(b,amodb)amodb=0amodb=0 也可以写作:
gcd(a,b)={agcd(b,amodb)b=0b=0 若a<b,则第一步实际上会交换两个数字的位置,因为必然有a÷b=0。每一步得到的余数amodb都会越来越小,必然存在一个数字r使得gcd(r,0)=gcd(a,b),r即为a,b的最大公约数。
设a0,b0为原始的a,b,用迭代式表达:
a0=a,b0=bgcd(a0,b0)=gcd(b0,a0modb0)=gcd(a1,b1)gcd(a1,b1)=gcd(b1,a1modb1)=gcd(a2,b2)gcd(a2,b2)=gcd(b2,a2modb2)=gcd(a3,b3)⋯gcd(ai,bi)=gcd(bi,aimodbi)=gcd(ai+1,bi+1)⋯gcd(an,bn)=gcd(bn,anmodbn)=gcd(an+1,0)→→→→→a1=b0,b1=a0modb0a2=b1,b2=a1modb1a3=b2,b3=a2modb2ai+1=bi,bi+1=aimodbian+1=bn,bn+1=0 对于第k步递归,有ak=bk−1,bk=ak−1modbk−1。迭代到第n+1步时得到an+1=bn,bn+1=0,an+1,bn即为最大公约数。
欧几里得算法的时间复杂度约为O(log2(max(a,b)))。
源码
Euclid.h
Euclid.cpp
测试
EuclidTest.cpp