2015-04-19 65 views
1

我剛剛開始使用Java編程,並編寫了一個程序以x次擲出一個x-面骰子。用戶輸入定義側面和輥的數量。該程序以JTable格式給出每個數字的絕對和相對頻率。一切運作良好,直到你選擇大量的側面和數量的卷。我得到一個ArrayIndexOutOfBoundsException,但在代碼中找不到任何相應的錯誤。骰子滾動 - ArrayIndexOutOfBounds

package rolling; 

import java.awt.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.JOptionPane; 

public class RollDice extends JPanel { 

    private static final long serialVersionUID = -6332129624300946462L; 
    JTable jt; 
    int i, k, j; //Counter for loops 

    /*========== CONSTRUCTOR CREATES TABLE OBJECT ==========*/ 
    public RollDice(int[] trial, int[] outcomes, int[] dice_numbers, 
    int[] count, float[] Rel_frequencies){ 

     String[] columnNames = {"Number of trial", "Outcome", "Dice Numbers", 
           "Absolute Frequencies", "Relative Frequencies"}; 

     Object[][] input = new Object[trial.length][columnNames.length]; 

     for (i=0; i<trial.length; i++){ 
      input[i][0] = trial[i]; 
     } 
     for (i=0; i<outcomes.length; i++){ 
      input[i][1] = outcomes[i]; 
     } 
     for (i=0; i<dice_numbers.length; i++){ 
      input[i][2] = dice_numbers[i]; 
     } 
     for (i=0; i<count.length; i++){ 
      input[i][3] = count[i]; 
     } 
     for (i=0; i<Rel_frequencies.length; i++){ 
      input[i][4] = Rel_frequencies[i]; 
     } 

     /*Checking the outcome! 
     for (i=0; i<trial.length; i++){ 
      System.out.println(); 
      for (k=0; k<columnNames.length; k++){ 
      System.out.printf("%d\t", input[i][k]); 
      } 
     }*/ 
     jt = new JTable(input,columnNames) 
     { 
      /** 
      * 
      */ 
      private static final long serialVersionUID = 1L; 

      public boolean isCellEditable(int input, int columns) 
      { 
       return false; 
      } 
      public Component prepareRenderer(TableCellRenderer r, int input, 
      int columns){ 
       Component c = super.prepareRenderer(r, input, columns); 

       if (input %2 == 0){ 
        c.setBackground(Color.WHITE); 
       } 
       else{ 
        c.setBackground(Color.LIGHT_GRAY); 
       } 
       if (isCellSelected(input, columns)){ 
        c.setBackground(Color.YELLOW); 
       } 
       return c; 
       } 
     }; 

     jt.setPreferredScrollableViewportSize(new Dimension(450, 600)); 
     jt.setFillsViewportHeight(true); 

     JScrollPane jps = new JScrollPane(jt); 
     add(jps); 
    } 

    public static int[] roll_dice(int sides, int rolls){ 
     int[] outcomes = new int[rolls]; 
     int i; //Counter for accessing array position (element) 
     for (i=0; i<rolls; i++){ 
      outcomes[i] = (int)(1 + Math.random() * sides); 
     } 
     return outcomes; 
    } 

    public static int[] Frequency_count(int[] outcomes, int sides){ 
     int[] count = new int[sides]; 
     int i; 
     int j, k = 0; 
     for(i=1; i<=sides; i++){ 
      for(j=0; j<outcomes.length; j++){ 
       if (outcomes[j] == i){ 
        count[k]++; 
       } 
      } 
      //System.out.printf("%d \t %d\n",i, count[k]); 
      k++; 
     } 
     return count; 
    } 

    public static float[] Relative_frequencies(int[] count, int sides, 
    int rolls){ 
     int i; 
     float[] Array = new float [sides]; 
     for(i=0; i<sides; i++){ 
      Array[i] = (float)count[i]/rolls * 100; 
      //String.format("%.3f", (float)Array[i]); 
      //System.out.printf("%d \t %.2f\n",i+1, Array[i]); 
     } 
     return Array; 
    } 

    public static void main(String[] args) { 
     /*=========USER INPUT via GUI: DECISION ON HOW MANY TIMES 
      THE DICE IS ROLLED===* 
     *=========  AND HOW MANY SIDES THE DICE HAS ===*/ 

     String fn = JOptionPane.showInputDialog("Enter the number of sides 
     of the dice"); 
     String sn = JOptionPane.showInputDialog("Enter the number of rolls"); 

     int sides = Integer.parseInt(fn); // number of sides 
     int rolls = Integer.parseInt(sn); // number of rolls 

     JOptionPane.showMessageDialog(null, "You rolled a " + sides + " 
     sided dice " + rolls + " times!", "User Input", 
     JOptionPane.INFORMATION_MESSAGE); 

     /*=========GENERATING RANDOM NUMBERS (ROLLING THE DICE) WITH 
     "roll_dice" method========== 
     *========= AND COUNTING THE NO. OF TRIALS  ==========*/ 
     int[] outcomes = roll_dice(sides, rolls); 
     int[] trial = new int[rolls]; 
     int[] dice_numbers = new int[sides]; 

     int i, k; 
     k = 1; 
     for(i=0; i<rolls; i++){ 
      trial[i] = k; 
      //System.out.println(i + " " + k); 
      k++; 
     } 
     k = 1; 
     for(i=0; i<sides; i++){ 
      dice_numbers[i] = k; 
      //System.out.println(i + " " + k); 
      k++; 
     } 
     /*=========COUNTING THE FREQUENCIES OF EACH NUMBER==========*/ 
     //System.out.println("ABSOLUTE Frequencies plotted in FUNCTION:"); 
     int[] count = Frequency_count(outcomes, sides); 
     //System.out.println("RELATIVE Frequencies plotted in FUNCTION:"); 
     float[] Rel_frequencies = Relative_frequencies(count, sides, rolls); 


     /*=========CREATING A TABLE FORMAT WITH A JAVA 
     LIBRARY (JTABLE)==========*/ 
     JFrame jf = new JFrame(); 
     RollDice table1 = new RollDice(trial, outcomes, dice_numbers, 
     count, Rel_frequencies); 
     jf.setTitle("Absolute and Relative Frequencies of numbers for 
     an arbitrary Dice"); 
     jf.setSize(500, 700); 
     jf.setVisible(true); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jf.add(table1); 
     } 
    } 
+1

發生異常的行號是什麼? –

+0

當我輸入「200」作爲兩岸和「100」爲我的電話號碼輥我收到此錯誤信息:
**異常線程「main」
java.lang.ArrayIndexOutOfBoundsException:100
\t在rolling.RollDice 。 (RollDice.java:36)
\t在rolling.RollDice.main(RollDice.java:162)**
因此,錯誤似乎有所有關輥的數目。
但是,在指定的第36行和第162行中找不到任何錯誤。 –

+0

@robby這是錯誤消息: **線程「main」java.lang.ArrayIndexOutOfBoundsException中的異常:100 \t at rolling.RollDice。 (RollDice.java:36) \t at rolling.RollDice.main(RollDice.java:162)** –

回答

0

看這裏的這部分代碼:

Object[][] input = new Object[trial.length][columnNames.length]; 

for (i=0; i<trial.length; i++){ 
    input[i][0] = trial[i]; 
} 
for (i=0; i<outcomes.length; i++){ 
    input[i][1] = outcomes[i]; 
} 
for (i=0; i<dice_numbers.length; i++){ 
    input[i][2] = dice_numbers[i]; 
} 
for (i=0; i<count.length; i++){ 
    input[i][3] = count[i]; 
} 
for (i=0; i<Rel_frequencies.length; i++){ 
    input[i][4] = Rel_frequencies[i]; 
} 

你有input二維數組設置到一定規模,但你訪問它沒有第二個想法。

例如,看看這個:

int[] trial = new int[rolls]; 
int[] dice_numbers = new int[sides]; 

假定用戶將輥2個骰子爲6邊骰子(常規骰子)。然後在第三個循環中,例如,您訪問input[i][2],其中我從0運行到5,但由於trial.length = 2,您正在訪問不存在的索引。

你應該檢查你的代碼,以便你只能在初始化時根據給定的邊界訪問你的數組(我不知道你的任務是否足以嘗試並提供更好的建議)。

+0

我認爲你提到的不是代碼的主要問題。通過爲每個元素提供足夠的空間來正確創建for循環,因爲我專門爲每個循環中的相應數組使用了「.length」運算符。 問題是,正如@RobbyCornelissen所指出的那樣,除非用戶決定設置'roll',否則前兩個數組的'trial'和'outcome'與另外三個數組'dice_numbers','count'和'Rel_frequencies' '和'大小'相等。 感謝您的反饋! –

0

看起來你總是會面對這個問題,如果你有更多的側面比卷。

初始化您的dice_numbersRelative_Frequencies陣列的長度等於邊的數量,但input陣列的第一維尺寸僅根據卷的數量而定。

接着,下面的代碼錯誤的片段,因爲你正在嘗試存儲陣列input的尺寸以外的位置值:

for (i=0; i<dice_numbers.length; i++){ 
    input[i][2] = dice_numbers[i]; 
} 
// ... 
for (i=0; i<Rel_frequencies.length; i++){ 
    input[i][4] = Rel_frequencies[i]; 
} 

如果我明白你正確地實現什麼,爲了快速修復,請將您的input陣列的尺寸標註爲較高者:邊數或卷軸數。

然而,你的程序的概念問題似乎是你試圖在同一個數組中存儲兩個不同的數據集,即一組關於實際卷軸及其結果的數據,以及一組關於邊的頻率分佈。

將這兩個組合分成兩個數組和兩個數據表可能會很快解決您所面臨的問題。

+0

謝謝,這很有幫助!儘管這很明顯,但我並沒有看到這一點。是否有可能在Java中創建具有靈活元素大小的非靜態多維數組? –

+0

@StefanStiller'static'或non-'static'並不真正考慮它。嚴格地說,Java中沒有靈活長度的數組。您可能想要開始查看Java集合。 –