【拾遗补阙】更相减损术&&辗转相除法
更相减损术
-
原理推导
- 设两个正整数为a、ba > b,根据辗转相除法的原理,a和b的最大公因数等于b和a - b的最大公因数。更相减损术就是基于这个原理,不断地用较大数减去较小数来逐步缩小两个数的范围,直到两个数相等,此时这个数就是最大公因数。
-
算法步骤
- 例如,求98和63的最大公因数。
- 第一步:因为98>63,所以98 - 63 = 35
- 第二步:此时63>35,则63 - 35 = 28
- 第三步:35>28,35 - 28 = 7
- 第四步:28>7,28 - 7 = 21
- 第五步:21>7,21 - 7 = 14
- 第六步:14>7,14 - 7 = 7
- 此时两个数相等,所以98和63的最大公因数是7
- 例如,求98和63的最大公因数。
-
代码实现(以C++为例)
-
int gcd(int a, int b) { while (a!= b) { if (a > b) { a = a - b; } else { b = b - a; } } return a; }
- 这段代码定义了一个函数
gcd
,它接受两个整数a
和b
作为参数。在函数内部,通过一个while
循环不断比较a
和b
的值。如果a
和b
不相等,就根据它们的大小关系用较大数减去较小数。当a
和b
相等时,循环结束,此时返回的a
(或b
,因为它们相等)就是原来两个数的最大公因数。
-
辗转相除法
- 原理推导
- 设两个正整数为 a、b,a > b,辗转相除法基于这样一个原理:a\和 b的最大公因数等于 b和 a除以b的余数。通过不断地用除数作为新的被除数,余数作为新的除数进行相除操作,直到余数为 0,此时的除数就是原来两个数的最大公因数。
- 算法步骤
- 例如,求 252 和 105 的最大公因数。
- 第一步:用 252除以105,商 = 2,余数= 42
- 第二步:把 105 作为新的被除数,42作为新的除数,得到新余数21
- 第三步:再把 42作为被除数,21 作为除数,此时余数为 0
- 所以 252和 105 的最大公因数就是最后的除数21
- 例如,求 252 和 105 的最大公因数。
- 代码实现(以 C++为例)
-
int gcd(int a, int b) { if(b>a) swap(a,b); while (b != 0) { int temp = a % b; a = b; b = temp; } return a; }
- 这段代码定义了一个函数
gcd
,它接受两个整数a
和b
作为参数。在函数内部,通过一个while
循环,只要除数b
不为 (0),就先计算 (a) 除以 (b) 的余数temp
,然后把除数b
的值赋给被除数a
,把余数temp
的值赋给除数b
,继续下一轮的计算。当b
为 (0) 时,循环结束,此时返回的a
就是原来两个数的最大公因数。
- 原理补充解释:
-
- 从更相减损术开始解释,假设a,b(a>b)的gcd(最大公因数)是x,则a=nx,b=mx,a-b=(n-m)x,所以a-b也可以被x整除;
-
- 例如,求98和63的最大公因数。
- 第一步:因为98>63,所以98 - 63 = 35,即14*7-9*7=5*7
- 第二步:此时63>35,则63 - 35 = 28,即9*7-5*7=4*7
- 第三步:35>28,35 - 28 = 7,即5*7-4*7=1*7
- 第四步:28>7,28 - 7 = 21,即4*7-1*7=3*7
- 第五步:21>7,21 - 7 = 14,即3*7-1*7=2*7
- 第六步:14>7,14 - 7 = 7,即2*7-1*7=1*7
- 此时两个数相等,所以98和63的最大公因数是7
-
- 咱们可以发现在不断的操作下,最后a,b都会等于1倍的gcd
- 极简更相减损术:
-
int gcd(int a, int b)
{
if (a < b) swap(a, b);
return (a == b) ? a : gcd(a - b, b);
}
- 对于上面的过程咱们可以发现对于同一个因子(1*7)减去了许多次,那么是否可以简化这一块的部分呢?
- 那也就是辗转相除法做到的事:a%b一定小于b,省去更相减损术中的判断和部分减去操作
- 极简辗转相除法:
int gcd(int a, int b)
{
return 0 == b ? a : gcd(b, a % b);
}