2009-08-15 16 views
2

私は、次の出力を持つヒストグラムプログラムを作成するための割り当てで、初心者のJavaクラスを取ります:(100と10はユーザー入力です)。Java(ヒストグラム)の初め

いくつの数字ですか? 100 間隔はいくつですか? 10

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

私のコードはあまり、誰も私が間違って何が起こっているかを指摘することができます、しかし、おかげで次のような出力を与えています。スレッド "メイン" java.lang.ArrayIndexOutOfBoundsExceptionで

例外:Lab6.mainで10 (Lab6.java:44入力について

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は、I、エラーメッセージを取得します)私は以下の行44をマークしました。

このコードには、次のリンクがあります。

   intervalValue[j]++; 

私は発電機(の.jar)ファイルを添付するかどうかはわかりませんが、ちょうど私たちのためにランダム# 'sのを発生することになっています。再度、感謝します。

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

残念ながら、私はジェネレータクラスなしではコンパイルできません。 – Kekoa

+1

であり、バイナリファイルのコンテンツを投稿しようとしないコードフォーマッタ(eclipseに組み込まれています)を使用することを検討することもできます。それは助けにはなりません:) –

答えて

0

eclipseのようなIDEを使用してプログラムを実行し、44行目を確認します。それがArrayIndexOutOfBoundsExceptionを取得する場所です。これは、あなたが債券から出ていないことを確認する必要がある場所です。 javaの配列にはインデックス0に最初の項目があるので、10個の配列の長さは0,1,2,3,4,5,6,7,8,9という番号が付けられます。それが10時に起こるなら、あなたはおそらく一歩遠くまで反復しているでしょう。 「intervalValue [j]」のjが10になっていないことを確認してください。

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

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

これらの行は正しい値を得るために変更する必要があります。なぜ彼らが現在間違っているのかを判断するために、「鉛筆と紙のデバッグ」を少し行います。


ここでは残りの部分を読者の練習として残しておきます。私は後であなたがさらに援助が必要かどうか確認するためにチェックインします。

+0

+1良い点は、それを逃した。 – Fredrik

0
intervalValue[j]++; 

jは数字の数まで行くが、これら二つの数はあなたがここで見ているエラーが発生します同じでなければintervalValueは、間隔の数から割り当てられています。

+0

どうすれば同じものにすることができますか、または少なくともエラーを作成しないでください。 -Thanks、 – Benzle

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]++; 


    } 

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

無限大のものは、ヒストグラムの最小値と最大値を捕捉することです。

+0

皆さんありがとうございました。これは、スタックオーバーフローに関する素晴らしい最初の体験でした。 – Benzle

1

これはあなたに非常に良い(基本的な)見た目のヒストグラムを与えるでしょう。私はつまり、配列の要素とその周波数(それが現れる頻度)二つの関連値を保持するHashMapを使用してい

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

:Outout

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

    } 

それを試してみてください。

次に、配列に沿って各要素をループし、c変数を使用してその頻度を数える入れ子になったループ。

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

+0

いくつかの言葉でコードを説明できますか?あなたの答えはずっと良くなり、より多くの票を得ることができます。 – Andrei

+0

私はHashMapを使用して2つの関連する値、つまり配列要素とその頻度(頻繁に出現する頻度)を保持しています。次に、配列に沿って各要素をループさせ、 "c"変数を使用して周波数を数える入れ子になったループ。その後、拡張ループと通常ループで印刷します。 – Amjad

+0

答えに説明を追加しました。機能では、あなたのコードを説明することを忘れないでください:)良い仕事! – Andrei

関連する問題