在c语言的学习中必然会遇到求两个数之间的最大公约数的题目,那么对于其他经典方法,最简便快捷的方式就是利用辗转相除法
辗转相除法又叫做欧几里得算法,目的是为了求两个正整数的最大公约数
定理:gcd(a,b) = gcd(b ,a%b) //在这里用(a,b)表示a和b的最大公约数
证明:a可以表示成a = kb + r,则r = a % b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a - kb,因此d|r //这里的"|"的意思是 :d是b的因数 ,d是a的因数
因此d是(b,a%b)的公约数
假设d 是(b,a%b)的公约数,则
d | b , d |r ,但是a = kb +r //同上意思
因此d也是(a,b)的公约数
因此(a,b)和(b,a%b)的公约数是一样的,其最大公约数也必然相等,得证
或许看不太懂,那么举个例子看看?
求 (495,319)=
解 495➗319=1......176
319➗176=1.......143
176➗143=1........33
143➗33=4.........11
33➗11=3..........0
即可得出 (495,319)=11 相当完美,理论成立 那么回归代码应该如何写呢?
#include <stdio.h>
int main()
{
printf("请依次输入需要取最大公约数的两位正整数:");
int x,y,z;
scanf("%d %d",&x,&y);
z=x%y;
while(z!=0) //while循环,当z余数不为0时开始循环,当z为0时跳出循环体,并打印结果
{
x = y; //将上一个除数赋值为被除数
y = z; //将上一个余数赋值为除数
z =x%y; //开始取余
}
printf("这两位正整数的最大公约数结果为:""%d" ,y);
return 0;
}
其运行结果如图:
这段代码貌似还能精进,我还没学到,学了再优化一下,因此最大公约数的求法就到这了
有问题请指教!
--------------------------------------------------------
21年11月29日
二次修改,这次加入自定义函数判断输入两位正整数大小,避免bug,并利用递归算法实现
#include <stdio.h>
void Swap(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int gcd(int x,int y)
{
if(y>x)
{
Swap(x,y);
}
if(x % y == 0)
{
return y;
}
else
return gcd(y,x%y);
}
int main()
{
int m ,n;
scanf("%d %d",&m,&n);
printf("最大公约数为%d",gcd(m,n));
return 0;
}
若还有更精进的方法,请告知!