0
点赞
收藏
分享

微信扫一扫

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

kiliwalk 2022-03-19 阅读 75
c++后端

什么是约数

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

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

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

以除数和余数反复做除法运算,当余数为 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并不是他们的最大公约数,所以应该反过来从最小的数本身开始

举报

相关推荐

0 条评论