最大公约数(GCD)

最大公约数(GCD)

求整数 a、b 的最大公约数,就是求同时满足 a%c=0、b%c=0 的最大正 整数 c,即求能够同时整除 a 和 b 的最大正整数 c。
在介绍欧几里得算法之前, 读者可能会有这样的思路:
若 a、b 均不为 0,则依次遍历不大于 a(或 b)的所有正整数,依次试验它是否同时满足两式,并在所有满足两式的正整数中挑选最 大的那个即是所求;
若 a、b 其中有一个为 0,那么最大公约数即为 a、b 中非零 的那个;
若 a、b 均为 0,则最大公约数不存在(任意数均可同时整除它们)。
这个朴素的思路是完全正确的,它的确能够正确的求得两个数的最大公约数。但是,该解法在大部分情况下要遍历不大于 a(或 b)的所有正整数,并依次测试它们是否满足条件,当 a 和 b 数值较大时(如 10000000)该算法的时间复杂度较高,耗费的时间较多,往往不能在指定时间内得到结果。

下面介绍一种更高效的方法:
若整数g为a,b(不同时为0)的公约数,则g满足:

a = g * l
b = g * m

其中l,m为整数。同时a可由b表示为下式:

a = b * k + r

其中k为整数,r为a除以b后的余数。那么对如上三式做如下变形:

g * l = g * m * k + r
r = g * (l - m * k)       (g不为0)

由上式可知,a,b的公约数g可以整除a除以b的余数r(记为a mod b)
即a, b的公约数同时也必是b, a mod b的公约数。

那么若g是a, b的最大公约数,它同样也是b, a mod b的最大公约数?
假设g是a, b 的最大公约数,但它并不是b,a mod b的最大公约数,即存在g’>g且g’同时整除b与a mod b。这样必存在整数l’与m‘使下式成立:

b = g' * m'
r = a mod b = g' * l'

同时a,b,r之间满足下式:

a = b * k + r
a = g' * m' * k + g' * l'
a = g' * (m' * k + l')      (g'不为0)

如上式g’同时也整除a,那么g’同时也是a,b的公约数。但是假设中a,b的最大公约数为g,而g’>g与假设不符,所以可证明a,b的最大公约数同时也是b, a mod b 的最大公约数。
这样,把求a,b的最大公约数转换成了求b, a mod b的最大公约数,那么问题不变而数据规模则明显变小,可以不断重复该过程,直到问题缩小成求某个非零数与零的最大公约数(该情况一定会发生)。这样,该非零数即是所求。

总结:若a,b全零则它们的最大公约数不存在;若a,b其中之一为零,则它们的最大公约数为a,b中非零的那个;若a,b都不为零,则使新a=b,新b=a%b,然后重复该过程。
这就是欧几里得算法,它改变了上文提到的朴素的枚举算法需要暴力遍历所有数字的情况,而利用数学原理将问题转换为规模更小的问题,从而最后得到答案。

你可能感兴趣的:(九度OJ)