C语言求最大公约数三种方法详解

题目要求

运行最大公约数的常用算法,并进行程序的调式与测试。

常用写法(穷举法)

从两个数中较小数开始由大到小列举,直到找到公约数立即中断列举,得到的公约数便是最大公约数 。

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;
}

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值