其他分享
首页 > 其他分享> > C语言求最大公约数,最小公倍数

C语言求最大公约数,最小公倍数

作者:互联网

什么是约数

约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。—选自百度百科

通俗的理解就是18%2==0,因此2就是18的约数,或叫做因数

那么公约数,其实就是几个数公有的约数.比如18和2的公约数,除了1以外,还有就是2了,而在这两个约数中,最大的是2,因此在这里2就是他们的最大公约数

最大公约数求法(辗转相除法)

假如需要求 12 和 8两个正整数的最大公约数,用欧几里得算法,辗转相除法,是这样进行的:
12%8= 1 (余 4)
8%4= 2 (余 0)

以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 12和 8的最大公约数 4。

这里其实有个让我很疑惑的点,明明是除数为最大公约数,为什么实际上拿的是被除数呢?这就要结合代码来看了

void main()
{
	int num1,num2;
	int restNum;
	int zdgys;
	scanf_s("%d,%d", &num1, &num2);

	do
	{
		restNum = num1 % num2;
		num1 = num2;
		num2 = restNum;			
	} while (restNum);

	zdgys = num1;

	printf("最大公约数=%d", zdgys);
}
  1. 根据辗转相除法规则,一开始余数=开始的除数%开始的被除数,接着将被除数变成除数,余数变成被除数
  2. 只要余数不为零,那就继续运算
  3. 到除数为零的时候,除数即为最大公约数

这里需要注意,因为在两个数是12和8时,第二次循环余数就成了0,而下面又把num2给了num1,造成了上面的问题

坑点

void main()
{
	int num1,num2;
	int restNum;
	int zdgys;
	scanf_s("%d,%d", &num1, &num2);

	restNum = num1 % num2;

	while (restNum)
	{
		num1 = num2;
		num2 = restNum;
		restNum = num1 % num2;		
	}

	zdgys = num2;

	printf("最大公约数=%d", zdgys);
}

有时会有这种辗转相除的写法,和上面的区别在于没有用do while,转而使用了while,因为是先判断条件,所以得在之前为余数赋值.
与此同时,因为把求余操作放在了最后,所以第二次执行完,余数就已经变成了0,因此不执行循环体了,所以被除数没有赋给余数,所以这里的最大公约数就是被除数了

暴力穷举解法

因为两个数当中,总归有一个大,有一个小,因此最大公约数就是从其中最小的一个数开始判断,如果能够被两个数同时除尽,那它就是最大公约数

void main()
{
	int num1, num2;

	scanf_s("%d,%d", &num1, &num2);

	int min;

	min = num1 < num2 ? num1 : num2;//判断两数当中最小的一个

	for (int i = min; i >= 1; i--)//从最小数开始判断是否能被除尽
	{
		if (num1%i==0&&num2%i==0)
		{
			printf("%d", i);
			break;
		}
	}
}

为什么不是正向循环呢?这是因为如果我正向从2开始,像12和8这两个数,都能够被2整除,但2并不是他们的最大公约数,所以应该反过来从最小的数本身开始

如有不足,还望指正

标签:num1,num2,公倍数,C语言,int,最大公约数,余数,restNum
来源: https://blog.csdn.net/wfy17030212/article/details/123600692