求两个数的最大公约数
常规方法
输入
要求两个数的最大公约数就要输入两个数
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); //输入
return 0;
}
公约数范围
两个数公约数的取值范围是从1到较小的那个数
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); //输入
int max = a; //设置最大的取值范围,假设取值范围从1到a
if (a > b) //如果a较大,则取值范围为从1到b
max = b;
return 0;
}
找最大公约数
定好范围后就能开始找公约数了
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); //输入
int max = a; //设置最大的取值范围,假设取值范围从1到a
if (a > b) //如果a较大,则取值范围为从1到b
max = b;
int n = 0; //创建一个变量来存储公约数
for (int i = 1; i <= max; i++) //从1开始找,到最大取值范围(较小的那个数)
{
if (a % i == 0 && b % i == 0) //能同时整除的就是公约数
n = i; //将公约数存在n中,随着循环进行公约数会越来越大
} //最后一次存的就是最大公约数
printf("%d", n); //打印
return 0;
}
辗转相除法
常规方法简单易懂,但在面对较大的数值时,效率较低。因为常规方法在找最大公约数时,会将每个数都求一遍
辗转相除法的效率就相对较高。辗转相除法只要计算除法和求余两个步骤就可以完成。
定义
辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。
证明
现有两个数a、b,a和b均为正整数,且a>b>0。
设a = bk + r, a和b的最大公约数为(a,b), b和r的最大公约数为(b,r)
因为 a % (a,b) = 0, b % (a,b) = 0
所以 bk % (a,b) = 0
又因为 r =(a - bk), (a - bk) % (a,b) = 0
所以 r % (a,b) = 0
又因为 b % (a,b) = 0, r % (a,b) = 0
所以 (b,r) % (a,b) = 0
到这步可以证明 b 和 r 的公约数里有(a,b)
又因为 b % (b,r) = 0, r % (b,r) = 0, (bk + r) % (b,r) = 0, a = bk + r
所以 a % (b,r) = 0
又因为n % (b,r) = 0, b % (b,r) = 0
所以 (a,b) % (b,r) = 0
所以 (a,b) = (b,r)
代码
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); //输入两个数
while (b != 0) //当余数为0时,则找到了最大公约数
{
int tmp = a % b; //将a/b的余数存在tmp中
a = b; //将这次的除数作为下次循环的被除数
b = tmp; //将这次的余数作为下次循环的除数
}
printf("%d", a);
return 0;
}
示例
输入 (被除数)a = 24,(除数)b = 18,求余(余数)tmp = a % b = 6
循环 (被除数)a = 18,(除数)b = 6, 求余(余数)tmp = a % b = 3
循环 (被除数)a = 6, (除数)b = 3, 求余(余数)tmp = a % b = 0
余数为0终止循环 a和b的最大公约数为a = 6