题目要求
运行最大公约数的常用算法,并进行程序的调式与测试。
常用写法(穷举法)
从两个数中较小数开始由大到小列举,直到找到公约数立即中断列举,得到的公约数便是最大公约数 。
int GreatestCommonDivisor1(int _x, int _y)
{
int temp = _x > _y ? _y : _x;//取出偏小的那个值
for (; temp > 2; temp--){ //从偏小的值由大到小找目标的最大公约数
if (_x%temp == 0 && _y%temp == 0){
return temp;
}
}
return 1; //最大公约数至少是1
}
辗转相减法
我们首先假设T为x和y的最大公约数
则易推知:x和y可以且一定是由若干个T相加得到的
若x>y,我们用x-y并将结果重新赋给x,此时相当于x变成了更少的T组成的了
我们继续通过循环判断x和y的大小,用大值减去小值…
最终一定会把T减到为0个,也就是x和y相等的时候…
int GreatestCommonDivisor2(int _x, int _y)
{
while (1) //辗转相减直到_x和_y相等;引用死循环
{
if (_x > _y)
{
_x = _x - _y;
}
else if (_y > _x)
{
_y = _y - _x;
}
else{
break; //相等时表明找到目标T,跳出循环
}
}
return _x; //任意返回_x或_y
}
辗转相除法
同样我们首先假设T为x和y的最大公约数
根据上述思想,我们可以当作x和y分别是由m个T和n个T构成的
那么通过辗转相减的思想可以理解为:T = mx (±) ny …(其中m和n未知但一定能通过数学思想解出)
进而我们来探讨:若x > y,我们用x / y = a…b【x➗y商为a余数为b】
接下来我们变形:x / y = a…b → x = y * a + b → b = x - a * y
对照 :T = mx (±) ny 与 b = x - a * y 我们变形出了一个很直接的等式;此时可以看出b相当于最大公约数T
用这个思想一直取模继续向下,最终x,y中一定会有一个值变为0,那么上一次循环中的b就是最大公约数。
int GreatestCommonDivisor3(int _x, int _y)
{
while (_x*_y != 0)//1.保证被除数不为零
//2._x和_y不是互相的倍数,否则直接返回较小那一个
{
if (_x > _y)
{
_x %= _y;
}
else if (_x < _y)
{
_y %= _x;
}
else{
break;
}
}
return _x == 0 ? _y : _x;//最终一定有一个变为0,它的上一次循环返回的值就是T
}
main函数
int main()
{
printf("请输入两个数:");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
int ret = GreatestCommonDivisor1(x, y);//变函数名实现调用
printf("这两个数的最大公约数为:%d\n", ret);
system("pause");
return 0;
}
整体代码
#include<stdio.h>
#include<Windows.h>
#pragma warning(disable:4996)
int GreatestCommonDivisor1(int _x, int _y)
{
int temp = _x > _y ? _y : _x;//取出偏小的那个值
for (; temp > 2; temp--){ //从偏小的值由大到小找目标的最大公约数
if (_x%temp == 0 && _y%temp == 0){
return temp;
}
}
return 1; //最大公约数至少是1
}
int GreatestCommonDivisor2(int _x, int _y)
{
while (1) //辗转相减直到_x和_y相等;引用死循环
{
if (_x > _y)
{
_x = _x - _y;
}
else if (_y > _x)
{
_y = _y - _x;
}
else{
break; //相等时表明找到目标T,跳出循环
}
}
return _x; //任意返回_x或_y
}
int GreatestCommonDivisor3(int _x, int _y)
{
while (_x*_y != 0)//1.保证被除数不为零
//2._x和_y不是互相的倍数,否则直接返回较小那一个
{
if (_x > _y)
{
_x %= _y;
}
else if (_x < _y)
{
_y %= _x;
}
else{
break;
}
}
return _x == 0 ? _y : _x;//最终一定有一个变为0,它的上一次循环返回的值就是T
}
int main()
{
printf("请输入两个数:");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
int ret = GreatestCommonDivisor1(x, y);//变函数名实现调用
printf("这两个数的最大公约数为:%d\n", ret);
system("pause");
return 0;
}