用 Java 洗一副纸牌

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39557701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:14:38  来源:igfitidea点击:

Shuffle a deck of cards in Java

javaalgorithmduplicatesshuffle

提问by Illy P.

I've read many things on the topic, but I am still having misgivings about it. Please, help!

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

I create a deck of 52 cards:

我创建了一副 52 张牌:

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

Now, I'd like to shuffle the deck properly, not by following any pattern or function.

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

I am going to use the Math.random()method in my algorithm:

我将在我的算法中使用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;
}

The problem I am having here, however, is that I sometimes might get duplicates; as a result, some cards/values are missing altogether.

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

I am almost certain that I am not discarding the indices/values I have already used, which is probably the core of the abovementioned problem. But how do I go about it?

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

Any suggestions? Possibly, following my same train of thought. Thanks a bunch!

有什么建议?可能,按照我的思路。谢谢一堆!

screenshot 1

截图 1

screenshot 2

截图 2

回答by Fayaz

Please look if this helps:

请看看这是否有帮助:

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

Idea is to use a Randomto generate a random number between 0 and 52. Once a number is taken, we will mark it as taken in the boolean array init.So, next time the same number comes up, we again generate the random number until we get a number we haven't already taken.

想法是用aRandom生成一个0到52之间的随机数。一旦取了一个数,我们会在布尔数组中将其标记为已取init。所以,下次出现相同的数字时,我们再次生成随机数,直到我们获取我们尚未使用的号码。

回答by felipeptcho

Simply use a new array for the shuffled cards and fill it using random cards removed from the prior array.

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

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

Or just use Collections.shuffle():

或者只是使用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);
    }
}