求N个数的最大公约数和最小公倍数,.已知a0,a1,b0,b1,设某未知正整数x满足: (1)x和a0的最大公约数为a1; (2)x和b0的最小公倍数为b1; 求出满足该规则x的个数

一.题目分析
题目要求:
1.求N个数的最大公约数和最小公倍数
2.已知a0,a1,b0,b1,设某未知正整数x满足:
(1)x和a0的最大公约数为a1;
(2)x和b0的最小公倍数为b1;
求出满足该规则x的个数
题目思路:
(1)求N个数的最大公约数和最小公倍数
1.先求出N个数中的最大值和最小值
2.利用穷举法求最大公约数和最小公倍数
3.利用循环求出任意一个数被N个数整除的次数以及任意一个数把N个数整除的次数
4.如果求出的次数与N值相等,那么对应的这个被整除的数就是最大公约数,整除的数就是最小公倍数
(2)求出满足的x的个数
1.从1开始循环,到一个比较大数结束
2.如果存在一个数与a0的最大公约数为a1,记下这个数为X
3,接着去验证这个x与b0的最小公倍数是否等于b1,如果等于,则这个x是满足Hankson规则,记录个数的值加
二.算法构造
1.求N个数最大公约数和最小公倍数的流程图

在这里插入图片描述

2.求出满足条件x的个数
在这里插入图片描述

三.算法实现
程序源代码:
package harkson;
import java.util.Scanner;//导包
public class Harkson {
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);//创建键盘录入对象
System.out.println(“求N个数的最大公约数和最小公倍数”);
System.out.println(“请输入N的值”);
int N=sc.nextInt();//用来存储需要求最大公约数的个数
System.out.println(“请输入N个数据:”);
int data[]=new int[N];
for(int i=0;i<N;i++)
{
data[i]=sc.nextInt();
}
gcdAndLcm(data);//求最大公约数和最小公倍数的方法
System.out.println("--------------");
System.out.println(“请输入数据的组数::”);
int M=sc.nextInt();
//定义一个二维数组来存储数据,M代表数据的组数,4分别代表a0,a1,b0,b1;
int[][] array=new int[M][4];
for(int j=0;j<M;j++)
{
System.out.println(“请输入第”+(j+1)+“组数据”);
array[j][0]=sc.nextInt();//键盘录入
array[j][1]=sc.nextInt();
array[j][2]=sc.nextInt();
array[j][3]=sc.nextInt();
}
//已知x,a0的最大公约数为a1,x,b0的最小公倍数为b1;
//所以a0>=a1;b1>=b0;,
//所以利用dataValidation方法对输入数据的规范性进行验证
if(dataValidation(array,M)==1)
{
harkson(array,M);//求出满足harksO规定的x值
}

}

//判断输入数据的规范性
public static int dataValidation(int array[][],int N)
{
	int leap=1;//判断循环是否提前结束的变量
	for(int j=0;j<N;j++)
	{
		if(array[j][2]>array[j][3])//判断a0>=a1;b1>=b0关系式是否成立
			if(array[j][1]>array[j][0])
			{
				System.out.println("输入数据不符合规则");//如果不成立,则输入数据不符合规则
				leap=0;
				break;
			}
		
	}
	return leap;//利用返回值来判断harskon方法是否继续进行
}

//利用harkson提出的方法,求出满足条件的x的个数
public static void harkson(int array[][],int N)
{
	for(int j=0;j<N;j++)//利用循环,求出每一组数据x的个数
	{
		int x=0;
		int ans=0;
		for(int i=1;i<10000;i++){
            if(gcd(i,array[j][0])==array[j][1]) {//gcd方法为求俩个数的最大公约数
                x=i;//如果x和a0的最大公约数是a1,满足第一条规则,再用这个x来验证第二条规则
        if(lcm(x,array[j][2])==array[j][3]) {//lcm方法为求俩个数的最小公倍数
                ans++;//如果x和b0的最小公倍数是b1,满足第二条规则,记录x个数的ans变量++
                System.out.println("x="+x);
                }
            }
		}
        System.out.println("满足x个个数为:"+ans);
        }
			
}

//求出俩个数的最大公约数
public static int gcd(int a,int b)
{
	if(a%b==0)
		return b;
	else
		return gcd(b,a%b);//递归
}

//求出俩个数的最小公倍数
public static int lcm(int a,int b)
{
    return a*b/gcd(a,b);//a*b除以a和b的最大公约数
}

//求出N个数的最大公约数和最小公倍数
public static void gcdAndLcm(int data[])
{
	int max=data[0],min=data[0];
	for(int j=1;j<data.length;j++)//求出N个数的最大值
	{
		if(data[j]>max)
	         max=data[j];
		}
	for(int j=1;j<data.length;j++)//求出N个数的最小值
    {
		if(data[j]<min)
			min=data[j];
    }
    int gcd=0;//最大公约数
    int m;
    for(int j=min;j>0;j--)//穷举法
    {
    	m=0;//记录可以被j整除的数的个数
    	for(int k=0;k<data.length;k++)
    		if(data[k]%j==0)
    		{
    			m++;
	        }
    	if(m==data.length)//可以整除j的个数与总数相等,则证明每一个数都整除j,则j为最大公约数
        {
    		gcd=j;
            System.out.println("最大公约数为:"+gcd);
            break;
        }
    }
    //求N个数的最小公倍数的方法与求最大公约数的方法一样,使用穷举法
    int lcm=0;//最大公倍数
    for(int l=max;;l++)
    {
    	m=0;
        for(int k=0;k<data.length;k++)
        	if(l%data[k]==0)
        	{
        		m++;//记录能整除的个数
        		}
        if(m==data.length)
        {
        	lcm=l;
            System.out.println("最大公倍数为:"+lcm);
            break;
        }
        }
}

}
四.调试、测试、及运行结果
调试:
一开始由于没有考虑到静态变量的关系,直接给max和min变量的初值设置成0,所以在求最大公约数的那个循环里,直接跳出了循环,没有执行这个循环

在这里插入图片描述
在这里插入图片描述

最后将max和min的初值设置成输入N数中第一个数值,就避免了该错误。
测试:
测试求N个数的最大公约数和最小公倍数

在这里插入图片描述

在这里插入图片描述

结果:
在这里插入图片描述

测试输入数据的正确性
在这里插入图片描述

结果:

在这里插入图片描述

测试求满足x的条件的个数
在这里插入图片描述
在这里插入图片描述

结果:

在这里插入图片描述

运行结果:

在这里插入图片描述

五。经验归纳
1.在写程序的时候,尽可能将一些比较长的代码放到一个方法中,使用的时候进行调用,这样所写的程序看起来不会太过繁琐。
2.写完程序以后,可以在网上看看其他人所写的程序。对比一下自己与别人的区别,总结一下各自代码的优缺点。
3.写完程序以后,及时的对一些代码进行注释,方便自己和别人理解。

猜你喜欢

转载自blog.csdn.net/weixin_44382383/article/details/88751129
今日推荐