2015-04-19 68 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集合。 –