Java实现最大公约数和最小公倍数的逆问题

一.题目名称

“求N个数的最大公约数和最小公倍数”

二.题目内容

用C/C++/Java/Python实现程序解决问题。
已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1。

输入第一行为一个正整数n,表示有n组输入数据。接下来的n行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证a0能被a1整除,b1能被b0整除。
输出格式
输出共n行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的x,请输出0;
若存在这样的x,请输出满足条件的x的个数;
样例输入

1
2
3
2  
41 1 96 288
95 1 37 1776

样例输出

1
2
6
2

三.算法设计

1.输入n,以及利用对n循环输入a0,a1,b0,b1
2.求最大公因数,定义一个数组x,利用循环将符合条件的值存放在数组x中
3.求最小公倍数,定义一个数组y,利用循环将符合条件的值存放在数组y中
4.遍历比较数组x和y,存在相等数值时,count++

改进:2,3定义一个数组,将符合条件的值赋给数组
4.遍历数组,当其值不为0时进行count++

四.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
   import java.util.Scanner;
public class Hankson {
public static void main(String[] args) {
System.out.println("请输入一个正整数n,表示有n组输入数据");
Scanner A = new Scanner(System.in);
int n = A.nextInt();
System.out.println("接下来的n行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证a0能被a1整除,b1能被b0整除。\n");
for (int i=0;i<n;i++) {
Scanner B = new Scanner(System.in);
int a0 = B.nextInt();
int a1 = B.nextInt();
int b0 = B.nextInt();
int b1 = B.nextInt();
greatest(a0,a1,b0,b1);
}
}
public static void greatest(int a0,int a1,int b0,int b1) {
int []x=new int[100];
int i=0;
int count=0;
for(int num=b1;num>=1;num--){
if(a0%a1==num%a1&&b1%b0==b1%num&&b0%num!=0){
x[i]=num;
i++;
}
}

for (int j=0;j<x.length;j++){
if(x[j]!=0){
count++;
}
}
System.out.println(count);
}
}

五.测试

1.符合条件的值输出测试

失败
问题1:32,24等数字并不符合96与它的最小公倍数为288,这些数字与96的最小公倍数为96本身。
问题2:不能取到大于41而且满足条件的值
改进:加上条件b0%num!=0;更改for循环中的num初始值

成功

2.符合条件的值个数测试

由于java好像无法在不清楚数组长度的时候定义。要先声明数组长度,不然系统不会为他分配内存空间。所以符合条件的个数不能通过x.length返回。

成功

3.输入另一组数据测试

出现错误,数组越界异常
更改数组长度为100

成功

4.同时输入2组进行测试最开始输入n行的循环代码

成功

六.调试

1.在进行最大公因数测试的时候出现问题,对此模块进行调试

1.1发现低级错误,由于将int i=0写在循环里面,所以每次循环只改变x[0]的值
1.2发现定义2个数组太浪费了,于是改成定义数组,同时满足2个已知条件的时候,在进行赋值。
2.对输入2组数据进行调试

由于执行到要从键盘输入数据的时候会跳出,显示没有变量
所以现在还不知道怎么实现先输入2行数据回车后,再输出每一行对应的结果

七.总结

1.利用循环操作的时候一定要细心书写循环的条件
2.进行算法设计的时候考虑空间时间问题
3.数组定义的必须得先定义一个长度
对于第二组数据,我感觉结果不止2个,好像测试输出的222,444,111等也可以