【问题标题】:Dice Rolling - ArrayIndexOutOfBounds掷骰子 - ArrayIndexOutOfBounds
【发布时间】:2015-06-26 02:14:43
【问题描述】:

我刚开始使用 Java 编程并编写了一个程序来滚动 x 次骰子。边数和卷数由用户输入定义。该程序以JTable 格式给出每个数字的绝对频率和相对频率。在您为边数和卷数选择大数字之前,一切正常。我收到了ArrayIndexOutOfBoundsException,但在代码中找不到任何相应的错误。

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

【问题讨论】:

  • 异常发生在哪一行?
  • 当我输入“200”作为边数并输入“100”作为我的卷数时,我收到以下错误消息:
    **线程“main”中的异常
    java.lang .ArrayIndexOutOfBoundsException: 100
    at rolling.RollDice.(RollDice.java:36)
    at rolling.RollDice.main(RollDice.java:162)**
    因此错误似乎与卷数有点相关。
    但是,我在指示的第 36 行和第 162 行中找不到任何错误。
  • @robby 这是错误消息:线程“main”中的异常 java.lang.ArrayIndexOutOfBoundsException: 100 at rolling.RollDice.(RollDice.java:36) at rolling.RollDice .main(RollDice.java:162)
  • 您的输入数组有rolls 行,小于sides。 (对于您的 100 和 200 测试用例)。在第 36 行,您从 i = 0 循环到 i i &lt; Rel_frequencies.length,而 Rel_frequencies.length 是您的 sides 号码。因此,当i &gt; rolls 出现异常时,由于输入数组中该索引处不存在行,它只有100 行。
  • 感谢您的反馈!

标签: java arrays swing


【解决方案1】:

看这里的这段代码:

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 2D 数组设置为特定大小,但随后您不假思索地访问它。

例如,看看这个:

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

假设用户掷出 2 个骰子,得到一个 6 面骰子(传统骰子)。然后在第三个循环中,例如,您访问 input[i][2],其中 i 从 0 运行到 5,但是由于 trial.length = 2,您访问的是不存在的索引。

您应该检查您的代码,以便仅在初始化期间根据给定的界限访问您的数组(我对您的任务了解不够多,无法尝试提出更好的建议)。

【讨论】:

  • 我认为您解决的问题不是代码的主要问题。通过为每个元素提供足够的空间来正确创建 for 循环,因为我专门为每个 for 循环中的相应数组使用了“.length”运算符。问题是,正如@RobbyCornelissen 指出的那样,除非用户决定设置“rolls”,否则前两个数组“trial”和“outcomes”的大小与其他三个数组“dice_numbers”、“count”和“Rel_frequencies”的大小不同和“大小”相等。感谢您的反馈!
【解决方案2】:

如果您的面数多于卷数,您似乎总是会面临这个问题。

您将 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 数组的维度设置为较高者:边数或滚动数。

但是,您的程序的概念问题似乎是您试图将两个不同的数据集存储在同一个数组中,即一组关于实际滚动及其结果的数据,以及一组关于两侧的频率分布。

将这两个集合拆分为两个数组和两个数据表可能会大大有助于解决您面临的问题。

【讨论】:

  • 谢谢,很有帮助!虽然很明显,但我一开始并没有看到这一点。是否有可能在 Java 中创建具有灵活元素大小的非静态多维数组?
  • @StefanStiller static 或非static 并没有真正考虑到它。严格来说,Java 中没有灵活长度的数组。您可能想开始研究 Java 集合。
猜你喜欢
  • 1970-01-01
  • 2018-09-08
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 2014-04-21
  • 2015-12-24
相关资源
最近更新 更多