如何交错两个数组列表? [英] How to interlace two array lists?

查看:21
本文介绍了如何交错两个数组列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

Deck(int n) 是构造函数.该参数说明应洗牌的轮数.在每一轮洗牌中,首先将整个牌组分成两个子牌组.然后子甲板交织成一整副甲板.

一些注意事项:

  • 为了简化讨论,我们假设卡片是 1、2、……、10.

  • 第一轮,全副牌分为[1, 2, 3, 4, 5]和[6, 7, 8, 9, 10].然后我们通过将它们交错为 [1, 6, 2, 7, 3, 8, 4, 9, 5, 10] 来组合两个子牌组.

  • 在第二轮中,我们再次将整个牌组分成两个子牌组 [1, 6, 2, 7, 3] 和 [8, 4, 9, 5, 10] 然后将它们组合成[1, 8, 6, 4, 2, 9, 7, 5, 3, 10].

  • 因为我们总是将牌放在第二副副牌之前的第一副副牌中,所以无论我们洗多少轮,副牌中的第一张牌和最后一张牌都保持不变.

  • 牌组原来的顺序是S2, S3, ..., SK, SA, H2, ..., HA, C2, ..., CA, D2, ..., DA.

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

我的隔行扫描方法:创建 3 个数组列表,其中 2 个(cards1cards2)保存卡片 SA - HA 和 C2- DA 和另一个(洗牌)拿着交错的甲板.我设法实现了原始的甲板顺序,但是当我尝试交错时,出现越界错误:Index 0 out of bounds for length 0".

问题:我做错了什么?

这是我的代码:

import java.util.*;公共课甲板{私人整数轮;私有 ArrayList卡片 = 新的 ArrayList();私有 ArrayListcard1 = new ArrayList();私有 ArrayListcard2 = new ArrayList();私有 ArrayListshuffled = new ArrayList();公共甲板(int n){for (Suit s : Suit.values()) {for (Rank r : Rank.values()) {card.add(new Card(r,s));}}for (int x=0; x

公共类卡片{私人排名;私人西装;公卡(军衔,西装套装){this.rank = 等级;this.suit = 西装;}公共字符串 toString() {返回套装+"+等级;}}

公共枚举套装{铲(S"),炉"),俱乐部(C"),钻石(D");私人字符串套装;西装(字符串){西装 = s;}公共字符串 toString() {退回诉讼;}}

//你不能修改这个文件公共枚举排名{二(2"),三(3"),四(4"),五(5"),六(6"),七(7"),八(8"),九(9"),十(10"),杰克(J"),皇后(问"),国王(K"),ACE("A");私人字符串等级;//构造函数排名(字符串 r){等级 = r;}公共字符串 toString() {回归排名;}}

公共类TestDeck {公共静态无效主(字符串 [] args){甲板甲板;甲板=新甲板(0);System.out.println("原来的牌组是:");for (int i = 0; i <52; i++) {System.out.print(deck.drawCard() + " ");}System.out.println();System.out.println();甲板=新甲板(1);System.out.println("洗牌一次后是:");for (int i = 0; i <52; i++) {System.out.print(deck.drawCard() + " ");}System.out.println();System.out.println();甲板=新甲板(2);System.out.println("洗牌两次后是:");for (int i = 0; i <52; i++) {System.out.print(deck.drawCard() + " ");}System.out.println();System.out.println();}}

class TestDeck 的假设输出是

原来的牌组是:S2 S3 S4 ... DK DA洗牌一次后是:S2 C2 S3 C3 ... DA洗牌两次后是:S2 H2 C2 D2 ... DA

解决方案

好吧,亲爱的,实际上你得到了一个索引越界"(天知道为什么...... :),这是我解决它的方法(附评论)):

公共类甲板{//52 和 26 的常量:private static final int FULL_DECK = Suit.values().length * Rank.values().length;私有静态最终 int HALF_DECK = FULL_DECK/2;//使用常量,我们只需要一个列表(+2 个临时列表,扔掉//shuffeld"(不需要,令人困惑,我们使用卡片"来表示完整牌组")):私有最终 ArrayList卡片 = 新的 ArrayList<>(FULL_DECK);公共甲板(int n){在里面();//正如你所拥有的/见下文//更多概述/结构......我们可以限制 n:for (int rounds = 0; rounds < n % 8; rounds++) {交错();}//对此进行注释,因为我们在 main 方法中输出...//System.out.println(cards);}

初始化 &交错"方法:

 private void init() {for (Suit s : Suit.values()) {for (Rank r : Rank.values()) {card.add(new Card(r, s));}}}私有无效隔行(){//抛出异常,当非法状态断言 (!cards.isEmpty());//左 &正确的临时列表:最终的 ArrayListleft = new ArrayList<>(HALF_DECK);最终的 ArrayList右 = 新 ArrayList<>(HALF_DECK);//将卡片"的前半部分放入左"left.addAll(cards.subList(0, HALF_DECK));//...其余的变成正确的"right.addAll(cards.subList(HALF_DECK, FULL_DECK));//清除卡片"卡片清除();//迭代半副牌:for (int i = 0; i < HALF_DECK; i++) {//从左"填充卡片(使用双步")card.add(i * 2, left.get(i));//..and from "right" (with "double step" +1;)card.add(i * 2 + 1, right.get(i));}//完毕!//调试://System.out.println(left);//System.out.println(right);//System.out.println(cards);}

draw"方法如下:

 public Card drawCard() {断言 (!cards.isEmpty());返回cards.remove(0);}

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

原来的牌组是: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 DQ D10DK DA洗牌一次后是: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 HK DJ HQ D哈达洗牌两次后是: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 HKHA计算机辅助设计

这不是那个"线程安全的……但是为了演示目的……希望它有所帮助!:)

..而且索引实际上越界了,因为你从未填充shuffledwhen n == 0 ... Main: System.out.print(deck.drawCard() + " "); (and (n == 0))>

I am trying to develop a program that shuffles a deck by dividing the deck into two and then interlacing them.

Class Deck represents a deck of 52 cards. There are two methods: Deck(int n) and Card drawCard().

Deck(int n) is the constructor. The parameter tells how many rounds the deck should be shuffled. In each round of shuffling, the whole deck is first divided into two sub-decks. The sub-decks are then interlaced into one whole deck.

Some notes:

  • To simplify the discussion, we assume the cards are 1, 2, …, 10.

  • In the first round, the whole deck is divided into [1, 2, 3, 4, 5] and [6, 7, 8, 9, 10]. We then combine the two sub-decks by interlacing them to [1, 6, 2, 7, 3, 8, 4, 9, 5, 10].

  • In the second round, we again divide the whole decks into two sub-decks [1, 6, 2, 7, 3] and [8, 4, 9, 5, 10] and then combine them to [1, 8, 6, 4, 2, 9, 7, 5, 3, 10].

  • As we always put the cards in the first sub-deck before the second sub-deck, the first card and the last card of the deck remains the same no matter how many rounds we shuffle.

  • The original order of the deck is S2, S3, …, SK, SA, H2, …, HA, C2, …, CA, D2, …, DA.

Card drawCard() removes the first card in the deck and returns it. Refer to the deck after the second round in the above discussion, drawCard() returns 1 and the deck becomes [8, 6, 4, 2, 9, 7, 5, 3, 10].

My method of interlacing: Create 3 array lists wherein 2 of them (cards1 and cards2) held the cards SA - HA and C2 - DA and the other (shuffled) held the interlaced deck. I managed to implement the original deck order, however when I try to interlace, I get an out of bounds error: "Index 0 out of bounds for length 0".

Question: What am I doing wrong?

Here are my codes:

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

The supposed output for class TestDeck is

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

解决方案

Ok, dear, actually you get a "index out of bounds" (god knows why... :), here is how i solved it (with comments):

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

init & "interlace" methods:

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

the "draw" method would go like this:

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

And with the same main method (Suit, Rank classes), we get:

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 

It's not "that" thread safe ...but for demo purpose... hope it helps! :)

..and the index out of bounds actually, because you never filled shuffeled, when n == 0 ... iobex at Main: System.out.print(deck.drawCard() + " "); (and (n == 0))

这篇关于如何交错两个数组列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆