求N个数的最大公因数和最小公倍数问题
想法思路
基本要求的解决:(1)写出求两个数的最大公约数
(2)写出求两个数的最小公倍数
(3)利用循环和递归求N个数的最大公约数和最小公倍数
1.求两个数的最大公约数实现流程图:
2.求两个数的最小公倍数实现流程图:
3.利用循环和递归求N个数的最大公约数和最小公倍数实现流程图如图 2-3 所示:
代码片段
int min,max;
void gcd(int a,int b) //最大公约数
{
int temp;
if(a<b) //总使得a>b
{
temp=a;
a=b;
b=temp;
}
while(b!=0)
{
temp=a%b;
a=b;
b=temp;
}
max=a;
}
void lcm(int c,int d) //最小公倍数
{
min=c*d/max;
}
int main()
{
int x[100];
int n;
cout<<"请输入你将要查询的数目个数"<<endl;
while(cin>>n)
{
for(int i=0;i<=n-1;i++)
{
cin>>x[i];
}
gcd(x[0],x[1]);
lcm(x[0],x[1]);
if(n>2)
{
for(i=2;i<=n-1;i++)
{
gcd(max,x[i]);
lcm(min,x[i]);
}
}
cout<<"这些数字的最大公约数为:"<<max<<endl;
cout<<"这些数字的最小公倍数为:"<<min<<endl;
}
}
测试调试与测试截图
(1)调试步骤
1.在函数gcd,函数lcm,主函数前F9加入断点。
2.F5启动调试,调试数据(以三个数字,2,4,5为例)
F10单步调试,最后一个数字循环输入完成
3.输入完成后,可以看到i=2,x[i]=5。
4.x[0]=2,x[1]=4。
5. 2小于4,进行数据交换
6.执行完temp=a%b。可以看到结果temp=0。
7.执行a=b;
8.执行b=temp 。
9.此时光标移到while循环,判断b是否为0。
10.判断不为0后,光标移至max=a处。
11.开始求x[0],x[1]的最小公倍数。
12.得到c=x[0]=2,d=x[1]=4,max=2。
13.计算得到min=4。
14.进行n的判断,如果数组超过两个数,将从第三个数开始进行循环。
15.同之前的步骤,第三个数循环完成,2,4,5得到结果max=1,min=20。
16.调试结束,按Shift+F5退出调试界面。
(2)测试
1.数组中含有0。
2.数组中含有1。
3.数组中含有重复数字。
4.多数据测试
感悟
刚开始的想法是写递归函数,gcd(x[i],x[i+1],i),通过i的不同来使得数组的元素进行求最大公约数和最小公倍数运算。但是数组不能做形参,形参不能被分配空间,只能做实参。然后就想着先写出两个数的运算,之后再对数组进行循环调用函数。
在调试的过程中,发现了在求最小公倍数的时候,最小公倍数中嵌套了最大公约数的函数,导致最大公约数又执行了一遍,因为之前max已经求出来,不必要再进行这个操作,所以对此进行了优化,删去了gcd(c,d);语句。
优化前:
优化后:
hanks son问题
问题描述:“逆问题”,已知正整数a0,a1,b0,b1,求某未知正整数x满足:
1.x和a0的最大公约数为a1
2.x和b0的最小公倍数为b1
(x并不唯一,也有可能不存在)
代码片段:
void gcd(int a,int b) //最大公约数
{
int temp;
if(a<b) //总使得a>b
{
temp=a;
a=b;
b=temp;
}
while(b!=0)
{
temp=a%b;
a=b;
b=temp;
}
max=a;
}
void lcm(int c,int d) //最小公倍数
{
gcd(c,d); //数据改变,max随之改变,基础程序删掉的得加上
min=c*d/max;
gcd(x,a0); //归原max
}
int main()
{
int ans=0; //计数器
int n,a;
cout<<"请输入您将使用的数据组数"<<endl;
cin>>n;
while(n--)
{
cout<<"请输入a0,a1,b0,b1"<<endl;
cin>>a0>>a1>>b0>>b1;
for(x=0;x<=x*b0;x++)
{
gcd(x,a0);
lcm(x,b0);
if((a1==max)&&(b1==min))
{
// cout<<x<<endl; 可查看x的值
ans++;
}
}
cout<<"满足要求的x个数为:"<<ans<<endl;
ans=0; //使ans回归为0,以便后面的数据组进行计数
}
}
解决过程
先进行一组样例输入程序的编写,编写后程序没有错误,但是结果与样例不同。通过单步调试(基础程序已详细展示调试过程,此处不进行展示),发现了两个问题:
解决方案实现程序:
利用循环进行多组输入,运算,此时的问题:计数器ans在进行完第一组数据的时候并未归0,所以第二组数据输出的ans是加上了第一组的ans。
例:输入样例:
本来第二组的x个数应该为2,此时为8,出现错误。
解决:在循环的最后加上ans=0;使计数器归0。
提高程序完成!