2

我正在学习 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 at 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;
    }
}
4

6 回答 6

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;
        }
    }
}

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

于 2009-08-16T00:14:57.220 回答
2

您需要从第 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);

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


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

于 2009-08-15T16:19:59.930 回答
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循环和普通循环打印它

于 2014-05-19T13:39:48.617 回答
0

您的数组异常似乎是由两次使用 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]++; 


  }

}
于 2009-08-16T00:08:30.483 回答
0

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

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

于 2009-08-15T16:19:06.110 回答
0
intervalValue[j]++; 

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

于 2009-08-15T16:25:15.553 回答