首页 > 解决方案 > 如何交错两个数组列表?

问题描述

我正在尝试开发一个程序,通过将甲板分成两部分然后将它们交错来洗牌。

Class Deck代表一副 52 张牌。有两种方法:Deck(int n)Card drawCard()

Deck(int n)是构造函数。该参数告诉甲板应该洗多少轮。在每一轮洗牌中,首先将整个牌组分成两个子牌组。然后将子甲板交错成一个完整的甲板。

一些注意事项

Card drawCard()移除牌组中的第一张牌并将其返回。参考上面讨论的第二轮后的deck,drawCard()返回1,deck变成[8,6,4,2,9,7,5,3,10]。

我的隔行扫描方法:创建 3 个数组列表,其中 2 个(卡片 1和卡片2)持有卡片 SA - HA 和 C2 - DA,另一个(洗牌)持有隔行扫描的牌组。我设法实现了原始的甲板顺序,但是当我尝试交错时,我得到一个越界错误:“索引 0 超出长度 0 的范围”。

问题:我做错了什么?

这是我的代码

import java.util.*;

public class Deck {
    private int rounds;
    private ArrayList<Card> cards = new ArrayList<Card>();
    private ArrayList<Card> cards1 = new ArrayList<Card>();
    private ArrayList<Card> cards2 = new ArrayList<Card>();
    private ArrayList<Card> shuffled = new ArrayList<Card>();

    public Deck(int n) {
        for (Suit s : Suit.values()) {
            for (Rank r : Rank.values()) {
                cards.add(new Card(r,s));
            }
        }

        for (int x=0; x<n; x++) {
            for (int i=0; i<((cards.size())/2); i++) {
                cards1.add(cards.get(i));
                for (int j=26; j<cards.size(); j++) {
                    cards2.add(cards.get(j));
                    for (int k=0; k<cards.size(); k++) {
                        shuffled.add(k*2, cards1.get(i));
                        shuffled.add(k*2+1, cards2.get(j));
                    }
                }
            }
        }

        System.out.println(cards);
        System.out.println(cards1);
        System.out.println(cards2);
        System.out.println(shuffled);
        rounds = n;
    }

    public Card drawCard() {
        Card removed = shuffled.get(0);
        shuffled.remove(0);
        return removed;
    }
}


public class Card {
    private Rank rank;
    private Suit suit;

    public Card (Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public String toString() {
        return suit + "" + rank;
    }
}

public enum Suit {
    SPADE("S"), 
    HEART("H"), 
    CLUB("C"), 
    DIAMOND("D"); 

    private String suit;

    Suit (String s) {
      suit = s;
    }

    public String toString() {
      return suit;
    }
}
// YOU CANNOT MODIFY THIS FILE

public enum Rank {
  TWO("2"), 
  THREE("3"), 
  FOUR("4"), 
  FIVE("5"), 
  SIX("6"), 
  SEVEN("7"), 
  EIGHT("8"),
  NINE("9"), 
  TEN("10"), 
  JACK("J"), 
  QUEEN("Q"), 
  KING("K"),
  ACE("A"); 

  private String rank;

  // Constructor
  Rank (String r) {
    rank = r;
  }

  public String toString() {
    return rank;
  }
}

public class TestDeck {
  public static void main(String[] args) {

    Deck deck; 

    deck = new Deck(0);
    System.out.println("The original deck is: ");
    for (int i = 0; i < 52; i++) {
      System.out.print(deck.drawCard() + " ");
    }
    System.out.println();
    System.out.println();

    deck = new Deck(1);
    System.out.println("After shuffling once is: ");
    for (int i = 0; i < 52; i++) {
      System.out.print(deck.drawCard() + " ");
    }
    System.out.println();
    System.out.println();

    deck = new Deck(2);
    System.out.println("After shuffling twice is: ");
    for (int i = 0; i < 52; i++) {
      System.out.print(deck.drawCard() + " ");
    }
    System.out.println();
    System.out.println();
  }
}

TestDeck 类的假定输出是

The original deck is:
S2 S3 S4 ... DK DA

After shuffling once is:
S2 C2 S3 C3 ... DA

After shuffling twice is:
S2 H2 C2 D2  ... DA

标签: javaarraysloopsarraylistnested

解决方案


好的,亲爱的,实际上你得到了一个“超出范围的索引”(天知道为什么...... :),这是我解决它的方法(带有评论):

public class Deck {

    //constants for 52 and 26 :
    private static final int FULL_DECK = Suit.values().length * Rank.values().length;
    private static final int HALF_DECK = FULL_DECK / 2;
    // use the constants, we need only one list (+2 temp lists, throw away
    // "shuffeld" (not needed, confusing, we use "cards" for "full deck")):
    private final ArrayList<Card> cards = new ArrayList<>(FULL_DECK);
    public Deck(int n) {

        init(); // as you had/see below

        // more overview/structure ... and we can limit n:
        for (int rounds = 0; rounds < n % 8; rounds++) {
            interlace();
        }
        // comment this, since we do output in main method...
        // System.out.println(cards);
    }

初始化和“隔行扫描”方法:

    private void init() {
        for (Suit s : Suit.values()) {
            for (Rank r : Rank.values()) {
                cards.add(new Card(r, s));
            }
        }
    }

    private void interlace() {
        // throw exception, when illegal state
        assert (!cards.isEmpty());
        // left & right temp lists:
        final ArrayList<Card> left = new ArrayList<>(HALF_DECK);
        final ArrayList<Card> right = new ArrayList<>(HALF_DECK);
        // put the first half of "cards" into "left"
        left.addAll(cards.subList(0, HALF_DECK));
        // ...the rest into "right"
        right.addAll(cards.subList(HALF_DECK, FULL_DECK));
        // clear "cards"
        cards.clear();

        // iterate half deck:
        for (int i = 0; i < HALF_DECK; i++) {
            // fill cards from "left" (with "double step")
            cards.add(i * 2, left.get(i));
            // ..and from "right" (with "double step" +1;)
            cards.add(i * 2 + 1, right.get(i));
        }
        // done!
        // debug:
        // System.out.println(left);
        // System.out.println(right);
        // System.out.println(cards);
    }

“draw”方法是这样的:

    public Card drawCard() {
        assert (!cards.isEmpty());
        return cards.remove(0);
    }

并且使用相同的主要方法(Suit、Rank 类),我们得到:

The original deck is: 
S2 S3 S4 S5 S6 S7 S8 S9 S10 SJ SQ SK SA H2 H3 H4 H5 H6 H7 H8 H9 H10 HJ HQ HK HA C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK CA D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK DA 

After shuffling once is: 
S2 C2 S3 C3 S4 C4 S5 C5 S6 C6 S7 C7 S8 C8 S9 C9 S10 C10 SJ CJ SQ CQ SK CK SA CA H2 D2 H3 D3 H4 D4 H5 D5 H6 D6 H7 D7 H8 D8 H9 D9 H10 D10 HJ DJ HQ DQ HK DK HA DA 

After shuffling twice is: 
S2 H2 C2 D2 S3 H3 C3 D3 S4 H4 C4 D4 S5 H5 C5 D5 S6 H6 C6 D6 S7 H7 C7 D7 S8 H8 C8 D8 S9 H9 C9 D9 S10 H10 C10 D10 SJ HJ CJ DJ SQ HQ CQ DQ SK HK CK DK SA HA CA DA 

这不是“那个”线程安全的......但出于演示目的......希望它有所帮助!:)

..实际上索引超出范围,因为您从未填充过shuffeled n == 0... iobex at Main: System.out.print(deck.drawCard() + " ");(and ( n == 0))


推荐阅读