【问题标题】:IndexOutOfBoundsException while trying to shuffle deck [closed]尝试洗牌时出现IndexOutOfBoundsException [关闭]
【发布时间】:2013-06-22 04:41:36
【问题描述】:

我正在尝试洗牌。

public void shuffle()
{
    int rand1;
    int rand2;
    Random randomGenerator = new Random();

    for (int i = 0; i < deck.size(); i++) {

        // pick a random index between 0 and size of the deck - 1
        rand1 = randomGenerator.nextInt(10);
         rand2 = randomGenerator.nextInt(10);

        // swap rand1 and rand2
        Card temp = deck.get (rand1);
        deck.set(rand1, deck.get (rand2)); 
        deck.set(rand2, temp); 
    }
}

然后它说:

java.lang.IndexOutOfBoundsException; Index:8; size:4(in java.util.ArrayList)

怎么了?

【问题讨论】:

  • deck 有 10 张卡吗?你为什么不改用randomGenerator.nextInt(deck.size());

标签: java random shuffle


【解决方案1】:

这一行

rand1 = randomGenerator.nextInt(10);

应该是

rand1 = randomGenerator.nextInt(deck.size());

rand2 也是如此。

【讨论】:

    【解决方案2】:

    另一个灵魂(如果有人需要知道)

    创建一个包含 1 到 deck.size() 的列表。然后使用Collection.shuffle 对其进行随机播放。然后列表将以相同的可能性重新洗牌

    【讨论】:

      【解决方案3】:

      如果这不是家庭作业,请按照 @StinePike 的建议使用 Collections.shuffle。如果是,你应该知道你没有正确洗牌。也就是说,并非所有结果都具有同样的可能性。这是由您的算法生成的直方图(带有@Jason 的更正),将 3 个数字改组:

      [1, 2, 3]: ***********************
      [2, 3, 1]: ******************
      [3, 2, 1]: **********************
      [3, 1, 2]: ******************
      [2, 1, 3]: **********************
      [1, 3, 2]: **********************
      

      这就是正确算法产生的结果:

      [1, 2, 3]: *********************
      [2, 3, 1]: *********************
      [3, 2, 1]: *********************
      [3, 1, 2]: *********************
      [2, 1, 3]: *********************
      [1, 3, 2]: *********************
      

      Collections.shuffle(deck) 是正确的,如下所示:

      public static <T> void shuffle(List<T> deck){
          int rand;
          for (int i = 0; i < deck.size()-1; i++) {
              // We randomly choose rand between i (inclusive) and deck.size()-1
              rand = i + randomGenerator.nextInt(deck.size()-i);
      
              // swap i and rand
              T temp = deck.get(rand);
              deck.set(rand, deck.get(i)); 
              deck.set(i, temp);
          }
      }
      

      这是我用来生成直方图的代码。请注意,排列并不总是以相同的顺序出现,但相同的排列([2,3,1] 和 [3,1,2])始终不太可能出现。

      public static void main(String[] args) {
          Map<List<Integer>,Long> histogram = new HashMap<>();
          int logReps = 20;
          int scaleStar = logReps-7;
          List<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2,3));
          for (int i = 0; i<(1<<logReps); i++) {
              List<Integer> templist = new ArrayList<Integer>(list);
              badShuffle(templist);
              if( histogram.containsKey(templist)) {
                  histogram.put(templist,histogram.get(templist)+1L);
              } else {
                  histogram.put(templist,1L);
              }
          }
          for(Entry<List<Integer>,Long> entry : histogram.entrySet()) {
              System.out.print(entry.getKey()+": ");
              for (int i=0; i<(entry.getValue()>>>scaleStar); i++) {
                  System.out.print("*");
              }
              System.out.println();
          }
      }
      static Random randomGenerator = new Random();
      public static void badShuffle(List<Integer> deck){
          int rand1;
          int rand2;
      
          for (int i = 0; i < deck.size(); i++) {
      
              // pick a random index between 0 and size of the deck - 1
              rand1 = randomGenerator.nextInt(deck.size());
               rand2 = randomGenerator.nextInt(deck.size());
      
              // swap rand1 and rand2
              Integer temp = deck.get (rand1);
              deck.set(rand1, deck.get (rand2)); 
              deck.set(rand2, temp); 
          }
      }
      public static <T> void goodShuffle(List<T> deck){
          int rand;
          for (int i = 0; i < deck.size()-1; i++) {
              // We randomly choose rand between i (inclusive) and deck.size()-1
              rand = i + randomGenerator.nextInt(deck.size()-i);
      
              // swap i and rand
              T temp = deck.get(rand);
              deck.set(rand, deck.get(i)); 
              deck.set(i, temp);
          }
      }
      public static void libraryShuffle(List<Integer> deck){
          Collections.shuffle(deck);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-15
        • 1970-01-01
        • 2016-04-02
        • 2013-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多