C语言如何利用辗转相除法求最大公约数
作者:Sandm *
C语言利用辗转相除法求最大公约数
1. 首先要明确几个概念
最大公约数: 也叫最大公因数,是指俩个或多个整数公有约数中最大的一个。
例如,18 和 24的最大公约数是 6
最小公倍数:除0以外最小的一个公倍数就叫作这几个整数的最小公倍数
例如,18 和 24的最小公倍数是 72
2. 辗转相除法
用除数和余数反复做除法运算,当余数为0时,取当前算式除数为最大公约数
例如:求 1997 和 615 俩个正整数的最大公约数
因为:
1997 % 615 = 152 615 % 152 = 7 152 % 7 = 5 7 % 5 = 2 5 % 2 = 1 2 % 1 = 0
所以,1997 和 615 的最大公约数为 1
3. C语言代码实现
#include <stdio.h> int main() { int data1 = 0, data2 = 0; int m = 0; //该变量是中间变量,不能放在while函数的内部 scanf_s("%d %d", &data1, &data2); while ((m = data1 % data2) != 0) { data1 = data2; data2 = m; } printf("最大公约数为%d\n", data2); return 0; }
注意点:
对于求模运算符%,若是分数形式求余数的话,如果分子小于分母,则分子就是余数。
例如:2 % 5 = 0
而当不是分数形式求余数的话,即例如:18 % 24 时,可将 % 左边的内容看成是分子,而 % 右边的内容看成是分母。所以 18 % 24 = 18
这里有一个误区,不能将18 与 24 在都约去 6 的情况下去求它们的余数,所以 18 % 24(3 % 8)= 3 是错误的
而不管是 18 % 24 ,还是24 % 18 。它们的余数均不会成为0
如果知道了俩个数的最大公约数,那么其最小公倍数可以根据公式来确定
即最小公倍数 = 俩个数的乘积 / 最大公约数
C语言求最大公约数常见思路
辗转相除法
辗转相除法又称为欧几里得算法,用于求两数的最大公约数gcd(全称为greatest common divisor)
注意两数必须为非负整数a,b。用法为:用两数中较大的数(a1)除以较小的数(b1),得到余数(r1),再用b1除以r1得到余数r2,之后再用r1除以r2,反复进行,直到最后余数是0为止。最大公约数就是最后式子中的除数。
请看如下举例:
若用函数gcd(a,b)来表示,即gcd(a,b)=gcd(b,a%b),我们可以这样理解:3887 2231和2231 1656的最大公约数是相等的,依次类推、重复操作。
用表达式可以这样来表示:gcd(3887,2231)=gcd(2231,1656)=gcd(1656,575),直到最后到底gcd(a,b)=gcd(c,0),即gcd(3887,2231)=gcd(23,0)。
这里的c为a和b的最大公约数。
下面来看辗转相除法的图像说明
下面看算法实现:
算法实现一
代码中的a就相当于上述gcd(a,b)=gcd(c,0)中的c。当然还有利用此原理的其他写法,不过是大同小异,这里就不一一列举了。这里的if语句其实是多余的,因为通过辗转相除完全可以实现两数之间的互换。
算法实现二(函数递归法)
对辗转相除足够熟悉后,可以采用递归的方式,如算法实现三
算法实现三(递归思想)
总之一句话:除数除以余数,直到余数为0为止。
更相减损之术
更相减损之术出自我国《九章算术》,原文是这样的:
可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。
算法过程:大数减小数,得到的差用来替换之前的大数,如此反复,直到得出来的差与上次的减数相等。此时的这个差就是两者的最大公约数。
以 36 24为例(如下图):
可以这样表示:gcd(36,24)=gcd(24,12),即36 24和24 12的最大公约数是相等的。
下面来看代码实现
总归一句话:用大数减去小数,知道减数和差相等。
最后,当处理较大的数时,辗转相除法虽然在时间上有明显优势。但是,即使是这样,辗转相除法也同样存在缺陷,其在处理较大的素因数(也叫质因数,就是说一个数是另一个数的因数,本身又是质数,就叫做另一个数的素因数)时,缺陷就会显现出来。
当然,实现求取最大公约数还有很多其他方法,这里只进行了常见思路的讲解。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。