【问题标题】:Beginning Java (Histogram)Java 入门(直方图)
【发布时间】:2010-11-19 21:54:08
【问题描述】:

我正在学习 Java 初学者课程,任务是创建一个具有以下输出的直方图程序:(100 和 10 是用户输入)。

多少个数字? 100 间隔多少? 10

Histogram
--------------------------------------------------------
  1 ****(4)
  2 ******(6)
  3 ***********(11)
  4 *****************(17)
  5 **************************(26)
  6 *************************(25)
  7 *******(7)
  8 ***(3)
  9 (0)
 10 *(1)
--------------------------------------------------------

但是,我的代码给出了以下输出,谁能帮我指出出了什么问题,非常感谢。

How Many Numbers? 10
How Many Intervals? 10

Histogram
--------------------------------------------------------
 1 **********(10)
 2 **********(10)
 3 **********(10)
 4 **********(10)
 5 **********(10)
 6 **********(10)
 7 **********(10)
 8 **********(10)
 9 **********(10)
 10 **********(10)

对于输入,100 和 10 我收到错误消息:

线程“main”中的异常 java.lang.ArrayIndexOutOfBoundsException: 10 在 Lab6.main(Lab6.java:44) 我标记了下面的第 44 行。

哪些链接到此代码;

             intervalValue[j]++;

我不确定如何附加生成器 (.jar) 文件,它应该只是为我们生成随机 #。再次感谢。

mport java.util.Scanner;

public class Lab6 {

    public static void main(String[] args) {

        int numbers, intervals;
        double intervalWidth;

        double max, mins, range;

        Scanner keyboard = new Scanner(System.in);

        System.out.print("How Many Numbers? ");

        numbers = keyboard.nextInt();

        System.out.print("How Many Intervals? ");

        intervals = keyboard.nextInt();

        double [] generate = new double[numbers];

        generate = randomGenerator(numbers);

        max = maximum(generate);

        mins = minimum(generate);

        range = max - mins;

        intervalWidth = range / intervals;

        int [] intervalValue = new int[intervals];

        for (int i=0; i < generate.length; i++) {

            for (int j = 0; j<generate.length; j++){
                double imin = mins+j*intervalWidth;
                double imax = max +j*(intervalWidth);
                if(generate[i] >= imin && generate[i] < imax)
                    intervalValue[j]++;         //LINE 44
            }
        }

        System.out.println("Histogram");

        System.out.println("--------------------------------" +
                           "------------------------");

        for (int a=0; a < intervalValue.length; a++) {

            System.out.print(" " + (a+1) + " ");

            for (int b=0; b < intervalValue[a]; b++) {
                System.out.print("*"); 
            }

            System.out.println("(" + intervalValue[a] + ")");
        }
    }

    private static double [] randomGenerator(int number) {
        double [] generate;

        generate = Generator.getData(number);

        return generate; 
    }

    private static double maximum(double [] a) {

        double max = a[0];

        for (int i = 1; i < a.length; i++) {        
            if (a[i] > max) {
                max = a[i];
            }         
        }

        return max;
    }

    private static double minimum(double [] a) {

        double mins = a[0];

        for (int i = 1; i < a.length; i++) {
            if (a[i] < mins) {
                mins = a[i];
            }
        }

        return mins;
    }
}

【问题讨论】:

  • 很遗憾,如果没有您的生成器类,我无法编译它。
  • 并且您可能要考虑使用代码格式化程序(eclipse 内置了一个)也不要尝试发布二进制文件的内容。它没有帮助:)

标签: java histogram


【解决方案1】:

这将为您提供一个非常漂亮(基本)的直方图。试试看

import java.util.HashMap;
import java.util.Map;

public class Histogram {
    public static void main(String[] args) {
        int[] age = { 25, 26, 33, 26, 27, 21, 26, 33, 21, 33, 21, 38, 19, 19};


        HashMap<Integer, Integer> m = new HashMap<Integer, Integer>();

        for (int i = 0; i < age.length; i++) {
            int c = 0;

            for (int j = 0; j < age.length; j++) {
                if (age[i] == age[j]) {
                    c++;
                }
            }
            m.put(age[i], c);

        }

        System.out.println("Histogram\n------------");
        for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
            int key = entry.getKey();
            int value = entry.getValue();
            System.out.printf("%3d | ", key);
            for (int i = 0; i < value; i++) {
                System.out.print("=");
            }
            System.out.print(" " + value);
            System.out.println();
        }

    }

输出:

Histogram
------------
 33 | === 3
 19 | == 2
 21 | === 3
 38 | = 1
 25 | = 1
 26 | === 3
 27 | = 1

我使用 HashMap 来保存两个相关的值,即一个数组元素及其频率(它出现的频率)。

然后一个嵌套循环遍历数组中的每个元素,并使用 c 变量计算其频率。

然后我用for-each循环和普通循环打印它

【讨论】:

  • 你能用几句话解释一下代码吗?它会让你的答案变得更好,你可以获得更多的选票。
  • 我正在使用 HashMap 来保留两个相关值,即数组元素及其频率(它出现的频率)。然后一个嵌套循环遍历数组中的每个元素,并使用“c”变量计算其频率。之后我用增强的 for 循环和普通循环打印它
  • 在答案中添加了您的解释。在功能中不要忘记解释您的代码:) 干得好!
【解决方案2】:

因为我在星期六感觉很慷慨,所以我试了一下并重写了你的循环。

for (int j=0; j < generate.length; j++) {
    for(int i = 0; i < intervals; i++) {
        double imin = mins + i * intervalWidth;
        double imax = mins + (intervalWidth) * (i + 1);
        if(i == intervals - 1) imax = Double.POSITIVE_INFINITY;
        if(i == 0) imin = Double.NEGATIVE_INFINITY;

        if (generate[j] >= imin && generate[j] < imax) {
            intervalValue[i]++;
            break;
        }
    }
}

无穷大的东西是捕捉直方图中的最小值和最大值。

【讨论】:

  • 非常感谢大家,这是关于堆栈溢出的第一次很棒的体验!
【解决方案3】:

您的数组异常似乎是由两次使用 generate.length 引起的 - 不过,您粘贴的代码似乎是由此编辑的。

但是,除此之外,问题在于您的嵌套循环。除了第一个内部循环中的错误数组大小之外,您正在沿着正确的路线前进。 然后,在 if 语句中 - 你想增加那个值,如果它在正确的间隔内,那么单独增加那个值;使用您当前的代码,您每次都会递增它们中的每一个,这解释了输出。

获取您自己的代码并进行评论:

for (int i=0; i < generate.length; i++) {

  for (int j = 0; j<intervals; j++){ // could use intervalValues.length here; it's all preference
    double imin = mins+j*intervalWidth;
    double imax = mins +(intervalWidth)*(j+1);
    if(generate[i] >= imin && generate[i] < imax) 
        // for(int j1 = 0; j1 < intervalValue.length; j1++) <- this was causing the bad output
        /* I assume the j1 from your code was during a debug attempt. Changed back,
           since the preceeding loop has been removed */
        intervalValue[j]++; 


  }

}

【讨论】:

    【解决方案4】:

    需要去掉第 43 行末尾的分号:

    if(generate[i] >= imin && generate[i] < imax);
    

    分号导致您的if 块为空。结果,导致异常的行将无条件执行。

    解决该问题后,以下提示可帮助您开始进一步调试代码:


    看看你的内循环的终止条件:

    for (int j = 0; j<generate.length; j++)
    

    您正在迭代外部循环中生成的数字;所以你应该在你的内部循环中迭代间隔以确定每个生成的数字所属的间隔。


    查看您用于确定循环中当前间隔范围的代码:

    double imin = mins+j*intervalWidth;
    double imax = max +j*(intervalWidth);
    

    需要修改这些行以产生正确的值。做一些“纸笔调试”来确定它们当前出错的原因。


    我将把剩下的留给读者作为练习。我稍后再回来看看您是否需要任何进一步的帮助。

    【讨论】:

      【解决方案5】:
      intervalValue[j]++; 
      

      j 上升到数字的数量,但 intervalValue 是从间隔的数量分配的,如果这两个数字不一样,你会得到你在这里看到的错误。

      【讨论】:

      • 我怎样才能使它们相同,或者至少不产生错误? -谢谢,
      【解决方案6】:

      使用 Eclipse 之类的 IDE,运行您的程序并查看第 44 行在哪里。这就是你得到 ArrayIndexOutOfBoundsException 的地方,你需要确保你不会失去债券。 Java 中的数组在索引 0 处有第一项,因此 10 项长的数组将它们编号为 0、1、2、3、4、5、6、7、8、9。如果它发生在 10 点,那么您可能正在迭代一步。 当你到达那里时,确保“intervalValue[j]”中的 j 不是 10。

      没有完整的例外,编译或更正您粘贴的源代码中的行号的源代码。没有什么可做的了。弄清楚它会帮助你获得与实验室其他部分所提供的一样多的知识。试试看吧。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-04
        • 2015-07-29
        • 1970-01-01
        • 2017-04-05
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多