Java 我如何编写一个方法来重新排列卡片组中的卡片

Java 我如何编写一个方法来重新排列卡片组中的卡片,java,Java,我需要把一副牌分成两个包:上半部分和下半部分。这个新的卡片数组应该是这样的:第一张卡片从顶部封包开始,第一张卡片从底部封包开始,第二张卡片从顶部封包开始,第二张卡片从底部封包开始,等等。如果有奇数张卡片,那么顶部封包应该比底部封包多一张。甲板的顶部是阵列的前部 我该怎么做呢 下面是我创建的生成卡片组的方法(我认为它是有效的): 在你开始做你所说的之前,请注意,如果你想随机化一副牌的顺序,a不是一个好主意: 一个完美的法罗牌洗牌,其中的牌是完全交替的,被认为是最困难的纸牌操作技巧之一,因为它需要洗

我需要把一副牌分成两个包:上半部分和下半部分。这个新的卡片数组应该是这样的:第一张卡片从顶部封包开始,第一张卡片从底部封包开始,第二张卡片从顶部封包开始,第二张卡片从底部封包开始,等等。如果有奇数张卡片,那么顶部封包应该比底部封包多一张。甲板的顶部是阵列的前部

我该怎么做呢

下面是我创建的生成卡片组的方法(我认为它是有效的):


在你开始做你所说的之前,请注意,如果你想随机化一副牌的顺序,a不是一个好主意:

一个完美的法罗牌洗牌,其中的牌是完全交替的,被认为是最困难的纸牌操作技巧之一,因为它需要洗牌者将牌分成两个相等的牌堆,并在将半副牌推入对方时施加适当的压力。如果一个人能够连续完成八次完美的法罗出局洗牌,那么52张牌组将恢复到原来的顺序。如果一个人能在洗牌中做到完美,那么26次洗牌将颠倒牌组的顺序,另外26次洗牌将使其恢复到原来的顺序


另一方面,如果你想要随机洗牌,那么选择的方法是随机洗牌。从维基百科页面:

To shuffle an array a of n elements (indexes 0..n-1):
  for i from n − 1 downto 1 do
       j ← random integer with 0 ≤ j ≤ i
       exchange a[j] and a[i]
但是,请注意,根据您的随机性标准,标准Java随机数生成器可能不够:(也可以从Wikipedia页面:)

例如,许多编程语言和/或库提供的内置伪随机数生成器通常只有32位内部状态,这意味着它只能生成232个不同的数字序列。如果这样一个生成器被用来洗牌52张扑克牌,它只能产生52张扑克牌中很小的一部分!≈ 2225.6可能的排列。对于一个内部状态少于226位的生成器来说,不可能产生52个卡片组的所有可能排列。有人建议[需要引证]只有使用状态超过250位的生成器才能获得洗牌无偏的信心

是一个众所周知的随机数发生器,这将是足够的


编辑:对于原始问题的字面回答,我可能会这样做(包括测试方法):

最后,您不应该将其用于洗牌的原因:

 public static void main(String[] args) {
    int N = 52;
    String[] in = new String[N];
    String[] out = new String[N];
    for (int i = 0; i < N; ++i)
        in[i] = Integer.toString(i);

    for (int k = 0; k < 8; ++k)
    {
        perfectShuffle(in, out, N);
        System.out.println(Arrays.asList(out));

        String[] tmp = in;
        in = out;
        out = tmp;          
    }
}

我在这个问题上寻找类似的东西(洗牌JSONArray):

我最终制定了自己的洗牌方法。以您的示例为例,它类似于:

public Card[] shuffle(Card[] cards) {
    // Implementing Fisher–Yates shuffle
       Random rnd = new Random();
       for (int i = cards.length() - 1; i >= 0; i--)
       {
          int j = rnd.nextInt(i + 1);
          // Simple swap
          Card card = cards[j];
          cards[j] = cards[i];
          cards[i] = card;
       }
       return cards;
}

如果您能够替换非完美的洗牌,请尝试Collections.shuffle()。您的代码如下所示:

List card_list = Arrays.asList(cards);
Collections.shuffle(card_list);
或者正如@Mark Peters所指出的,越简洁:

Collections.shuffle(Arrays.asList(cards));

仅供参考,它们是梅花,不是三叶草。你最近一直没吃过幸运符麦片,是吗?……脸卡是杰克王后,而不是小丑皇后。@用户:考虑使用<代码> EnUM <代码>的值。@杰森:FIY。这已经讨论过很多次了。看看这个:和那个:(在许多其他例子中)。我将编辑来解释如何实现随机洗牌。否则这个问题就是一个没有实际意义的问题,我看不出这是如何接近于回答用户提出的问题的。这是一篇洗牌的好帖子,但这不是用户要求的,正如问题的评论所示,这个问题在其他地方已经被回答了很多次。@马克:很公平,添加了文字答案。方法签名应该简化为
静态公共无效perfectShuffle(Object[]输入,Object[]输出,int N)
为什么不直接使用
集合。shuffle
Collections.shuffle(Arrays.asList(cards))
@Mark这是我的第一个选择,但这样可以避免从阵列中创建列表并再次返回阵列。在我引用的问题中,我问了效率问题,但没有人给我答案。我甚至把它发布在代码审查上,唯一的评论是关于使用泛型的(这也是非常正确的)。我知道这个数组不是一个JSONArray,但问题是类似的,而且这样做的算法非常简单。我也不知道会有多少副牌同时洗牌。这种方法的一个缺点是它复制牌只是为了交换它们。即使它是一种可变类型(当然不应该是这种类型),也永远不应该需要它。只需重新分配卡片,而不是创建一张新卡片。好吧,看看最新的评论并阅读编辑过的问题,很明显我误解了原始问题。1)你应该使用泛型,2)你不需要做
toArray
行。我在@Aleadam's Response上发布的评论就是你所需要做的。谢谢Mark,我实际上正在调查新列表是否由原始数组支持,然后注意到你远远领先于我。是的……我需要学会在评论之前查看问题的时间戳:-)。
[0, 26, 1, 27, 2, 28, 3, 29, 4, 30, 5, 31, 6, 32, 7, 33, 8, 34, 9, 35, 10, 36, 11, 37, 12, 38, 13, 39, 14, 40, 15, 41, 16, 42, 17, 43, 18, 44, 19, 45, 20, 46, 21, 47, 22, 48, 23, 49, 24, 50, 25, 51]
[0, 13, 26, 39, 1, 14, 27, 40, 2, 15, 28, 41, 3, 16, 29, 42, 4, 17, 30, 43, 5, 18, 31, 44, 6, 19, 32, 45, 7, 20, 33, 46, 8, 21, 34, 47, 9, 22, 35, 48, 10, 23, 36, 49, 11, 24, 37, 50, 12, 25, 38, 51]
[0, 32, 13, 45, 26, 7, 39, 20, 1, 33, 14, 46, 27, 8, 40, 21, 2, 34, 15, 47, 28, 9, 41, 22, 3, 35, 16, 48, 29, 10, 42, 23, 4, 36, 17, 49, 30, 11, 43, 24, 5, 37, 18, 50, 31, 12, 44, 25, 6, 38, 19, 51]
[0, 16, 32, 48, 13, 29, 45, 10, 26, 42, 7, 23, 39, 4, 20, 36, 1, 17, 33, 49, 14, 30, 46, 11, 27, 43, 8, 24, 40, 5, 21, 37, 2, 18, 34, 50, 15, 31, 47, 12, 28, 44, 9, 25, 41, 6, 22, 38, 3, 19, 35, 51]
[0, 8, 16, 24, 32, 40, 48, 5, 13, 21, 29, 37, 45, 2, 10, 18, 26, 34, 42, 50, 7, 15, 23, 31, 39, 47, 4, 12, 20, 28, 36, 44, 1, 9, 17, 25, 33, 41, 49, 6, 14, 22, 30, 38, 46, 3, 11, 19, 27, 35, 43, 51]
[0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]
public Card[] shuffle(Card[] cards) {
    // Implementing Fisher–Yates shuffle
       Random rnd = new Random();
       for (int i = cards.length() - 1; i >= 0; i--)
       {
          int j = rnd.nextInt(i + 1);
          // Simple swap
          Card card = cards[j];
          cards[j] = cards[i];
          cards[i] = card;
       }
       return cards;
}
List card_list = Arrays.asList(cards);
Collections.shuffle(card_list);
Collections.shuffle(Arrays.asList(cards));