一个数的因数列表

5

这是我的第一篇帖子,如果我写了什么蠢话,请不要骂我。

我刚开始上IT课程,今天在“while”循环课上,我的导师给我们布置了以下作业:

编写一个程序,该程序读取自然数n,并在一个图形框中显示出它在区间[2; n-1]中的所有因子。

到目前为止,我想出了一个可行的代码,但结果有点错误:

import java.util.Arrays;
import javax.swing.JOptionPane;

public class Divisors {
    public static void main(String[] args) {
        String n = JOptionPane.showInputDialog(null, "Enter a natural number");
        Integer i = Integer.parseInt(n);

        int d = i - 1;
        int x = 2;
        int[] dvr = new int[i]; // [i] because bigger numbers need more iterations

        while (x >= 2 && x <= d) {
            double y = i % x;

            if (y == 0) {
                dvr[x] = x;
                x = x + 1;
            } else {
                x = x + 1;
            }
        }

        JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + Arrays.toString(dvr));
    }
}

问题在于该循环用许多零填充了数组,导师的结果截图显示了仅列出因子的窗口。
我尝试使用ArrayList来解决这个问题,但对我来说那是黑魔法,而且我的导师还没有教我们如何使用代码中未涉及的任何东西。
非常感谢任何帮助。

2
实际上,当您创建数组时,它会被初始化为所有零,您的循环并没有将其填充为零。 - azurefrog
1
你的问题出在 dvr[x] = x; 这一行。你不想设置位置 x 上的除数的值。你需要一个第二个变量来索引你的数组,每添加一个除数后只增加它的值。 - bhspencer
@bhspencer 但是我仍然在数组中有一个预定数量的插槽。 - Shamanix
@azurefrog 抱歉,我知道,是误输入。但有没有一种方法只显示除数?我想不出比将它们保存在数组中然后通过 showMessageDialog 显示更好的办法了... - Shamanix
我给出的答案只显示除数。 - azurefrog
1
这是我的第一篇帖子,如果我写了什么愚蠢的东西,请毫不留情地批评我。实际上,看到一个包括 mvce 和具体问题描述的问题是很令人耳目一新的。 - azurefrog
4个回答

4
你遇到的主要问题是你想打印未知数量的值,但你正在使用一个数组来存储它们,而数组有固定大小。由于你有一个int类型的数组,这个数组将完全被默认值零填充。
理想情况下,你只需要打印数组中第一串非零值,但你将约数分散存储在数组中。
"dvr[x] = x;"将每个值存储在该值的索引处,实际上你应该只把每个新值存储到数组中的下一个开放的位置。
创建一个单独的索引变量,并使用它存储每个值即可:
    int index = 0;
    while (x >= 2 && x <= d) {
    ...
        if (y == 0) {
            dvr[index++] = x;
    ...

当主循环完成后,您可以创建一个新的“展示数组”,其中仅包含除数而不是零。此时,index 将告诉您需要多大:

    int[] display = Arrays.copyOf(dvr, index);
    JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + Arrays.toString(display));

非常感谢!这是一个完美的解释。 - Shamanix

3

在Java中,int的默认值为零。这就是为什么你会看到很多零的原因。

由于您定义数组的大小为i,而除数的数量始终小于i,因此应该只打印到总除数的数量,而不是打印整个数组。为此,您应该使用一个单独的变量来跟踪除数的数量,而不是使用x

这是修改后的版本,我使用一个单独的index变量来跟踪从0开始的除数数量。最后,您只需打印数组,直到index即可。

import java.util.Arrays;
import javax.swing.JOptionPane;

public class Divisors {
public static void main(String[] args) {
    String n = JOptionPane.showInputDialog(null, "Enter a natural number");
    Integer i = Integer.parseInt(n);

    int d = i - 1;
    int index = 0;
    int x=2;
    int[] dvr = new int[i]; // [i] because bigger numbers need more iterations

    while (x >= 2 && x <= d) {
        double y = i % x;

        if (y == 0) {
            dvr[index] = x;
            x = x + 1;
            index= index + 1;
        } else {
            x = x + 1;
        }
    }

    JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + Arrays.copyOfRange(drv, 0, index));
}
}

问题在于,如果除数条件检查失败(请参见else部分),x变量也会被递增。因此,x实际上并不代表约数的数量。 - Ish
是的,问题已经解决了。 - pgiitu
1
一个 int 的默认值是零。 - Paul Boddington

1

Set 数据结构可以避免重复元素,你可以使用它来解决重复除数被添加到数据结构中的问题。

    import java.util.*;
    import javax.swing.JOptionPane;

    public class Divisors {
        public static void main(String[] args) {
            String n = JOptionPane.showInputDialog(null, "Enter a natural number");
            Integer i = Integer.parseInt(n);

            int d = i - 1;
            int x = 2;
            Set<Integer> divisors = new HashSet<>();

            while (x >= 2 && x <= d) {
                double y = i % x;

                if (y == 0) {
                     divisors.add(x);
                     x = x + 1;
                } else {
                     x = x + 1;
                }
            }

            List<Integer> l = new ArrayList<>(divisors);
            JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + l);
        }
    }

1
似乎OP不想要List或ArrayList的解决方案,因为这超出了OP类的范围。此外,这个答案没有对代码进行任何解释。 - But I'm Not A Wrapper Class
OP不想要的是他自己的问题,而不是他不能在不使用List、ArrayList、Set或任何集合类的情况下进展。关于解释,我会提供的。 - deepak marathe
@deepakmarathe,并不是我不想用,但是我的导师会检查我们的代码,并且批评那些使用他没有提及的工具的人。我知道这很糟糕,但总比什么都不用好... - Shamanix

1
使用ArrayList创建动态数组。
以下代码将帮助您。
在您的程序中需要更改以下内容。
  1. 导入java.util.*;
  2. 声明一个ArrayList变量
  3. 调用Arraylist对象上的toString方法
import java.util.*;
import javax.swing.JOptionPane;

public class NewClass3 {
    public static void main(String[] args) {
        String n = JOptionPane.showInputDialog(null, "Enter a natural number");
        Integer i = Integer.parseInt(n);

        int d = i - 1;
        int x = 2;
        List<Integer> dvr = new ArrayList<>();
        while (x >= 2 && x <= d) {
            double y = i % x;

            if (y == 0) {
                dvr.add(x);
                x=x+1;
            } else {
                x = x + 1;
            }
        }

        JOptionPane.showMessageDialog(null, "The divisors of " + i + " are:\n" + dvr.toString());
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接