P207: Determine the greatest common divisor of two positive integer numbers
求最大公约数。
最大公因数
最大公因数(英语:highest common factor,hcf)也称最大公约数(英语:greatest common divisor,gcd)是数学词𢑥,指能够整除多个整数的最大正整数。而多个整数不能都为零。例如8和12的最大公因数为4。 整数序列的最大公因数可以记为或。 求两个整数最大公因数主要的方法:
- 穷举法:分别列出两整数的所有因数,并找出最大公因数。
- 质因数分解:分别列出两数的质因数分解式,并计算共同项的乘积。
- 短除法:两数除以其共同质因数,直到两数互质时,所有除数的乘积即为最大公因数。
- 辗转相除法:两数相除,取余数重复进行相除,直到余数为0时,直到余数为0时,前一个除数即为最大公因数。wiki-hcf
照例先写测试用例:
「辗转相除法」是一个简单有效的求最大公约数的方法。
辗转相除法
在数学中,辗转相除法,又称欧几里得算法(英语:Euclidean algorithm),是求最大公因数的算法。辗转相除法首次出现于欧几里得的《几何原本》(第VII卷,命题i和ii)中,而在中国则可以追溯至东汉出现的《九章算术》。wiki-division
计算过程
辗转相除法是一种递回算法,每一步计算的输出值就是下一步计算时的输入值。设k表示步骤数(从0开始计数),算法的计算过程如下。
每一步的输入是都是前两次计算的非负余数和。因为每一步计算出的余数都在不断减小,所以,小于。在第k步中,算法计算出满足以下等式的商和余数:
其中。也就是要不断减去直到比小。
为求简明,以下只说明如何求两个非负整数a和b的最大公约数(负数的情况是简单的)。在第一步计算时(k = 0),设和分别等于a和b,第2步(此时k = 1)时计算(即b)和(第一步计算产生的余数)相除产生的商和余数,以此类推。整个算法可以用如下等式表示:
如果有,算法的第一步实际上会把两个数字交换,因为这时a除以b所得的商会等于0,余数则等于a。然后,算法的第二步便是把b除以a,再计算所得之商和余数。所以,对于总有,即运算的每一步中得出的余数一定小于上一步计算的余数。 由于每一步的余数都在减小并且不为负数,必然存在第N步时等于0,使算法终止,就是a和b的最大公因数。其中N不可能无穷大,因为在和0之间只有有限个自然数。wiki-division
完整的代码实现:
辗转相除法(euclid(a,b)
)是一个递归算法。其接受两个整数a和b,且a>b(所以需要在外层按大小排列好两个整数),求出余数r0
和r1
,r0 = a % b, r1 = b % r0
。
- 若
r0
为0则b
为最大公约数; - 若
r1
为0则r0
为最大公约数; - 若
r0
和r1
皆不为0则r0, r1
的最大公约数即是a, b
的最大公约数,问题被简化为求r0, r1
的最大公约数。
举个例子,输入整数36和63,求最大公约数:
- 63大于36,以63为a以36为b,求得
r0
为27,r1
为9。r0
和r1
皆不为0,所以求27和9的最大公约数。 - 27为a,9为b,求得
r0
为0则b9
为最大公约数。
参考文献
wiki-hcf. https://zh.wikipedia.org/wiki/最大公因数 ↩
wiki-division. https://zh.wikipedia.org/wiki/辗转相除法 ↩