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 に対して、次のエラー メッセージが表示されます。

Exception in thread "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 を使用して、配列要素とその頻度 (出現頻度) という 2 つの関連する値を保持しています。

次に、ネストされたループが配列に沿って各要素をループし、c変数を使用してその頻度をカウントします。

その後、for-eachループと通常のループで印刷します

于 2014-05-19T13:39:48.617 に答える
0

配列の例外は、generate.length を 2 回使用したために発生したように見えますが、貼り付けたコードはこれから編集されているようです。

ただし、これとは別に、ネストされたループに問題があります。内側のループの最初の配列サイズが間違っていることを除けば、正しい方向に進んでいます。次に、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 で発生した場合は、1 ステップ先まで反復している可能性があります。そこに着いたら、「intervalValue[j]」のjが10でないことを確認してください。

完全な例外、コンパイルするソース、貼り付けたソースの行番号の修正のいずれもありません。これ以上のことはありません。それを理解することは、ラボの残りの部分があなたに与えるのと同じくらい多くの知識を得るのに役立ちます. 試してみてください。

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

j は数値の数になりますが、 intervalValue は間隔の数から割り当てられます。これらの 2 つの数値が同じでない場合、ここに表示されているエラーが発生します。

于 2009-08-15T16:25:15.553 に答える