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);
}
- 根据辗转相除法规则,一开始余数=开始的除数%开始的被除数,接着将被除数变成除数,余数变成被除数
- 只要余数不为零,那就继续运算
- 到除数为零的时候,除数即为最大公约数
这里需要注意,因为在两个数是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