我的方法有效吗?

Pan*_*thy 7 java shuffle playing-cards

我正在为一副纸牌编写一个代码,这些卡片可以洗牌.我测试了代码,但我真的不知道它是否真的正在做它应该正确做的事情?你怎么看?

这是shuffle方法的代码:

public void shuffle()
{
    for( int x = myDeck.size(); x > 0 ; x--) 
     {
        Random rn = new Random();
        int index1 = rn.nextInt(52);
        Card c = myDeck.remove(index1);
        myDeck.add(c);
     }
  }
Run Code Online (Sandbox Code Playgroud)

我的输出似乎在它的数字中被洗牌,但不是像黑桃心脏卡这样的名字,

例如,当我测试代码时,这是我的输出:

Deuce of spades
Seven of spades
Eight of spades
Ace of spades
Three of hearts
Five of hearts
Six of hearts
Seven of hearts
Nine of hearts
Ten of hearts
Queen of hearts
King of hearts
Ace of hearts
Seven of diamonds
Eight of diamonds
Jack of diamonds
King of diamonds
Three of clubs
Seven of clubs
Nine of clubs
Jack of clubs
Queen of clubs
King of clubs
Ace of clubs
Queen of spades
Deuce of clubs
Three of spades
Nine of diamonds
Four of spades
Four of clubs
Deuce of hearts
Jack of spades
Ten of clubs
Six of diamonds
Jack of hearts
Six of clubs
Four of diamonds
Five of diamonds
Ace of diamonds
Four of hearts
Nine of spades
Ten of spades
Five of spades
Three of diamonds
Six of spades
Five of clubs
Deuce of diamonds
Eight of hearts
King of spades
Ten of diamonds
Eight of clubs
Queen of diamonds
Run Code Online (Sandbox Code Playgroud)

就像总有重复的名字一样.这是不对的,因为洗牌的目的是混淆它?

这是一个实际的问题:当打牌时,当然重要的是洗牌,即安排事情以便卡片以随机顺序处理.有几种方法可以实现这一目标.一种策略是从卡片中随机反复挑选卡片并将其移动到最后.下面的代码使用Random类(您在在线课程的"ArrayLists"部分的第8页上遇到)来执行一个这样的"选择并移动到最后"操作:

Random rn = new Random();
int index1 = rn.nextInt( 52 );
Card c = myDeck.remove( index1 );
myDeck.add( c );
Run Code Online (Sandbox Code Playgroud)

为了有效地洗牌,这个操作应该重复多次(比如500次).为Deck类创建一个新的实例方法shuffle,该类使用单个Random对象和for循环来重新调整myDeck.在适当修改main方法后,使用它来测试新代码.

所以我的主要问题是:我做错了吗?

aio*_*obe 16

只需换rn.nextInt(52);rn.nextInt(x)并且你有一个适当的Fisher-Yates shuffle.无需执行超过52次迭代.

为什么这样有效:

  • 在第一次迭代中(当时x为52),您将从完整的牌组中选择一张随机牌并最后移动它.

  • 在第二次迭代中(当时x为51),您将从剩余的卡中选择一张随机卡并将其移动到最后.

    ...等等.

  • 在52次迭代之后,选择的第一张卡将在第一个索引中结束.由于这张卡是从完整的牌组中随机选择的,因此每张牌都是同样可能的.

  • 同样适用于第二指数,第三指数,......

  • 因此,甲板的每种可能的排列都是同样可能的.


(在生产代码中,只Collections.shuffle在这些情况下使用.)