【问题标题】:Shuffle a deck of cards in Java [duplicate]用Java洗牌[重复]
【发布时间】:2017-01-26 05:31:23
【问题描述】:

我已经阅读了很多关于该主题的内容,但我仍然对此感到疑虑。 请帮忙!

我创建了一副 52 张牌:

int[] deck = new int[52]; 
for (int i = 0; i < deck.length; i++) {deck[i] = i;}

现在,我想正确地洗牌,而不是遵循任何模式或功能。

我将在我的算法中使用 Math.random() 方法:

for (int i = 0; i < deck.length; i++) {
    int j = (int)(Math.random() * deck.length); // Get a random index out of 52
    int temp = deck[i]; // Swap the cards
    deck[i] = deck[j];
    deck[j] = temp;
}

然而,我在这里遇到的问题是我有时可能会得到重复;结果,一些卡片/值完全丢失了。

我几乎可以肯定我没有丢弃我已经使用过的索引/值,这可能是上述问题的核心。但是我该怎么做呢?

有什么建议吗?可能,遵循我同样的思路。非常感谢!

screenshot 1

screenshot 2

【问题讨论】:

  • 复制什么? j的重复值? i 和 j ?什么?
  • 我随机生成和/或已经分配的副本
  • 你能给我们看一个你的输出有重复的例子吗?代码中似乎没有任何错误会产生重复。所以也许你测试重复的方式是错误的。
  • 当你生成随机数时,你会得到重复。洗牌时没有任何问题。
  • deck 应该是List&lt;Integer&gt;,然后你可以只是Collections.shuffle()

标签: java algorithm duplicates shuffle


【解决方案1】:

只需为洗好的卡片使用一个新数组,然后使用从先前数组中删除的随机卡片填充它。

import java.util.ArrayList;

public class Test {
    private static final int DECK_SIZE = 52;

    public static void main(String args[]) {
        ArrayList<Integer> deck = new ArrayList<Integer>();

        for (int i = 0; i < DECK_SIZE; ++i) {
            deck.add(i);
        }

        ArrayList<Integer> shuffledDeck = new ArrayList<Integer>();

        while (deck.size() > 0) {
            int index = (int) (Math.random() * deck.size());
            shuffledDeck.add(deck.remove(index));
        }

        System.out.println(shuffledDeck.toString());
    }
}

或者直接使用Collections.shuffle():

import java.util.ArrayList;
import java.util.Collections;

public class Test {
    private static final int DECK_SIZE = 52;

    public static void main(String args[]) {
        ArrayList<Integer> deck = new ArrayList<Integer>();

        for (int i = 0; i < DECK_SIZE; ++i) {
            deck.add(i);
        }

        Collections.shuffle(deck);

        System.out.println(deck);
    }
}

【讨论】:

  • 感谢您的帮助!
【解决方案2】:

请看看这是否有帮助:

boolean init[] = new boolean[52];
Random r = new Random();

int getNextCard(){
    int i = r.nextInt(52);
    while(init[i])
        i = r.nextInt(52);
    init[i] = true;
    return i;
}

void shuffleCards() {   

    int[] deck = new int[52];
    for (int i = 0; i < deck.length; i++) {
        deck[i] = getNextCard();
    }
    System.out.println(Arrays.toString(deck));
}

想法是使用Random生成一个介于0和52之间的随机数。一旦取了一个数字,我们将在布尔数组init中将其标记为已取。所以,下次出现相同的数字,我们再次生成随机数,直到我们得到一个我们还没有得到的数字。

【讨论】:

  • 这不是洗牌,这是重新填充。
  • 但这会产生一个洗牌集对吗?
  • 没错,顺序不同。但这不是问题。
  • 据我了解,他的洗牌方法会导致重复,因此会丢失一些其他值,我在代码中向他展示了一种不会导致重复的方法
  • 感谢您的帮助!
猜你喜欢
  • 2011-07-09
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
相关资源
最近更新 更多