程序【16】
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
程序分析:
(1)最小公倍数=输入的两个数之积除于它们的最大公约数,关键是求出最大公约数;
(2)求最大公约数用辗转相除法(又名欧几里德算法)
1)证明:设c是a和b的最大公约数,记为c=gcd(a,b),a>=b,
令r=a mod b
设a=kc,b=jc,则k,j互素,否则c不是最大公约数
据上,r=a-mb=kc-mjc=(k-mj)c
可知r也是c的倍数,且k-mj与j互素,否则与前述k,j互素矛盾,
由此可知,b与r的最大公约数也是c,即gcd(a,b)=gcd(b,a mod b),得证。
2)算法描述:
第一步:a ÷ b,令r为所得余数(0≤r 第二步:互换:置 a←b,b←r,并返回第一步。
由程序分析我们可以知道,求最大公约数和最小公倍数的方法很多,这就非常对应,一个程序可以由很多个编程思想。
在这里我将会使用辗转相除法来为大家展示怎么用代码去求得最大公约数
辗转相除法在程序里的思想是写出这道算法题的关键:
(1)辗转相除法
设有两整数a和b:
① a% b得余数c
② 若c == 0,则b即为两数的最大公约数
③ 若c! = 0,则a = b,b = c,再回去执行①。
就比如:
求27和15的最大公约数过程为:
27÷15 余12
15÷12 余3
12÷3 余0
因此,3即为最大公约数。
所以,我们可以根据以上的思想,写出辗转相除法在C程序中的表现
c = m % n;
d = m * n;
while (c != 0) {
m = n;
n = c;
c = m % n;
}
max = n;
当c == 0的时候,跳出循环,此时的n就是最大公约数。
而根据数学知识我们不难知道,最小公倍数=两数之积/最大公约数
所以,我们可以很容易的得到最小公倍数的代码展示
min = d / max;//最小公倍数=两整数的乘积÷最大公约数
最后,我们明白了最大公约数和最小公倍数的计算方法还有程序分析,将它们加到总程序里,就是下面这个总代码。
总代码::::
#include<stdio.h>
//输入两个正整数 m 和 n,求其最大公约数和最小公倍数
int main() {
int m = 0;//声明定义一个正整数m
int n = 0;//声明定义一个正整数n
int c = 0;//将m%n的值放进去
int d = 0;//将m*n的值放进去
int max = 0;//声明m和n的最大公约数
int min = 0;//声明m和n的最小公倍数
printf("输入两个正整数m和n:");
scanf_s("%d %d", &m, &n);
int a = m;//将输入的值m赋给a
int b = n;//将输入的值n赋给b
/*(1)辗转相除法
设有两整数a和b:
① a% b得余数c
② 若c == 0,则b即为两数的最大公约数
③ 若c! = 0,则a = b,b = c,再回去执行①。
例如求27和15的最大公约数过程为:
27÷15 余12
15÷12 余3
12÷3 余0
因此,3即为最大公约数。*/
c = m % n;
d = m * n;
while (c != 0) {
m = n;
n = c;
c = m % n;
}
max = n;
min = d / max;//最小公倍数=两整数的乘积÷最大公约数
printf("%d和%d的最大公约数是%d\n最小公倍数是%d\n", a, b, max, min);
return 0;
}
当然,有的人会担心,24和18,18和24结果不一样,希望前面的数字大后面的数字小 。首先,上述这个程序如果18在前24在后,在辗转相除的时候,自然就会交换。
那有的同学要说了,我就要先交换,不要辗转相除自动交换,那么这样的话,我们当然也可以去满足一下这个条件,我们只需要在辗转相除前加上判断条件就可以了。
if(a<b)
{t=b;b=a;a=t;}
这样的的话,就可以满足该同学的需求。
下面是这样写的总代码:
#include<stdio.h>
int main()
{
int a, b, t, r, n;
printf("请输入两个数字:\n");
scanf_s("%d %d", &a, &b);
if (a < b)
{
t = b; b = a; a = t;
}
r = a % b;
n = a * b;
while (r != 0)
{
a = b;
b = r;
r = a % b;
}
printf("这两个数的最大公约数是%d,最小公倍数是%d\n", b, n / b);
return 0;
}