Java 爪哇:洗牌一副32张牌?

Java 爪哇:洗牌一副32张牌?,java,methods,shuffle,Java,Methods,Shuffle,我自己写了这个方法,我想知道是否有更好的方法 public Card[] shuffle(){ for(int i = 0; i < Deck.length; i++){ int x = i + (int) (Math.random() * (32 - i)); Card temp = Deck[i]; Deck[i] = Deck[x]; Deck[x] = temp; } return Deck; } p

我自己写了这个方法,我想知道是否有更好的方法

public Card[] shuffle(){
    for(int i = 0; i < Deck.length; i++){
       int x = i + (int) (Math.random() * (32 - i));
       Card temp = Deck[i];
       Deck[i] = Deck[x];
       Deck[x] = temp;
    }
    return Deck;
}
public Card[]shuffle(){
对于(int i=0;i
我想,如果您从整副牌中选择要交换的物品,而不仅仅是从剩余的牌中选择,您可以得到更好的结果,如下所示:

public Card[] Shuffle(){
    for(int i = 0; i < Deck.length; i++){
       int x = (int) (Math.random() * 32);
       Card temp = Deck[i];
       Deck[i] = Deck[x];
       Deck[x] = temp;
    }
    return Deck;
}
public Card[]Shuffle(){
对于(int i=0;i
如果
(32-i)
给出的值小于
0
,则不进行检查。该算法称为洗牌算法,与您的算法非常相似:

private int [] shuffleMyArray ( int [] array ) {
    int size = array.length, i = 0;
    int temp = 0;
    while ( size != 0 ) {
        i = ( ( int ) ( Math.random () * size-- ) );
        if ( i < 0 ) {
            i = 0;
        }
        temp = array [ size ];
        array [ size ] = array [ i ];
        array [ i ] = temp;
    }
    return array;
}

我将使
成为一个参数,方法为静态。这样,它是独立的。在Java中,命名约定是使变量和方法名以小写字母开头。接下来,我知道的最短的方法是用或类似的方法将牌组洗到位

如果您想保留原始的
deck
,那么您可以复制它并
返回

public static Card[] shuffle(Card[] deck) {
    List<Card> al = new ArrayList<>(Arrays.asList(deck));
    Collections.shuffle(al);
    return al.toArray(new Card[deck.length]);
}
公共静态卡[]洗牌(卡[]牌组){
List al=新的ArrayList(Arrays.asList(deck));
收藏。洗牌(al);
返回到阵列(新卡[牌组长度]);
}

Collections.shuffle(convertArrayToCollectionHere)
看起来还不错。除了已经指出的明显的替代方案外,我建议采用Java命名约定,并对方法和变量名使用小写名称。@jangroth谢谢您的建议。@JigarJoshi我稍后将对此进行检查。因为我还不知道收藏。令人惊讶的是,从全系列中挑选一张卡片实际上更糟糕。是对实现错误的良好讨论;使用全量程是一个常见问题。@dasblinkenlight确实令人惊讶。谢谢你指出这一点。这可能会导致糟糕的洗牌,这意味着随机数可能永远不会从牌组中选择特定的牌。这种洗牌可能是有偏差的。用Fisher Yates来代替。在这里我发现了一个非常好的学习网站,是的,你是对的,我没有检查它。你能解释一下我为什么要这么做吗?因为很明显它永远不会小于零。@HaroutTatarian:你是对的,这一点。在这有限的时间里,我从未如此仔细地观察过,因为我正准备离开工作场所。现在,自从我来到这里,我设法提出了这两个算法的输出,只是为了检查,他们如何采取不同的指数交换。输出是描述性的,足以说明两者之间的区别,哪种方法更有效。@HaroutTatarian:如果我仔细观察,就像我现在仍然在做的那样:-),你的算法似乎和Fisher-Yates算法一样有效。我仍在测试它,将尝试更多的思考它。似乎你的算法是一个非常好的算法:-)即使你的算法以一种非常有效的方式获取每个索引,或者在某种程度上它类似于Fisher-Yates,只是在该算法中,一个是减少选择随机数的范围,你的只是以另一种方式减少,比如先0到4,然后1到4,然后2到4等等。。。
public static void shuffle(Card[] deck) {
    Collections.shuffle(Arrays.asList(deck));
}
public static Card[] shuffle(Card[] deck) {
    List<Card> al = new ArrayList<>(Arrays.asList(deck));
    Collections.shuffle(al);
    return al.toArray(new Card[deck.length]);
}