【问题标题】:Trouble getting a card shuffle method to work无法让洗牌方法发挥作用
【发布时间】:2014-02-18 03:21:18
【问题描述】:

问题描述如下:

“shuffle 方法通过循环遍历 Card 对象数组一次一个位置并随机交换(参见数组讲座的幻灯片 62-63)在该位置的 Card 和 Card 来随机打乱 Card 对象数组位置(由随机数确定)在 0 到 51 之间。”

我已经编写了以下代码来执行上述操作,但它并没有洗牌我的卡片对象。

public void shuffle()
{
    //reset nextCard to 0.
    nextCard = 0;

    Random randomGen = new Random();
    Card tempCard;

    int randomNum = randomGen.nextInt(DECK_SIZE);

    int i;
    for(i=0;i<DECK_SIZE;i++)
    {
        tempCard = deck[i];
        deck[i] = deck[randomNum];
        deck[randomNum] = tempCard;
    }//end for.
}//end shuffle().

有什么问题,我该如何解决?

P.S.我会根据要求发布控制台输出。

【问题讨论】:

  • 您应该在循环内生成randomNum,如果它与i相同,请尝试再次生成它

标签: java shuffle


【解决方案1】:

您应该为for 循环的每次迭代生成randomNum

像这样重写你的循环会给你预期的结果,

int randomNum;
int i;
for(i=0;i<DECK_SIZE;i++)
{
    randomNum = randomGen.nextInt(DECK_SIZE);
    tempCard = deck[i];
    deck[i] = deck[randomNum];
    deck[randomNum] = tempCard;
}//end for.

【讨论】:

  • 随机笔记 - 可能不是均匀分布的。看看the Fisher-Yates shuffle - 这是一个众所周知的算法,看起来与此相似(当然有一些显着差异)。
  • 非常感谢。 @杜克林
  • 谢谢你@Karthik Kalyanasundaran 我欠你的,它成功了!
【解决方案2】:

@Karthik 的方法不正确,因为它使用 randomGen.nextInt(DECK_SIZE) 每次返回一个数字 [0..DECK_SIZE-1]。您真正想要的是将 DECK[i] 与 [DECK[i+1]..DECK[N-1]] 值之一交换,该值是尚未使用的剩余值之一。这称为 Knuth shuffle。

public static void shuffle(int[] a)
{
    int N = a.length;
    for (int i = 0; i < N; i++)
    { // Exchange a[i] with random element in a[i..N-1]
        int r = i + StdRandom.uniform(N-i);
        int temp = a[i];
        a[i] = a[r];
        a[r] = temp;
    }
}

【讨论】:

  • 不错。非常好。我用了他的,所以他值得回答,但这是正确的,我听说过 Knuth shuffle 但不知道如何实现它,谢谢你给我看这个。 +1
猜你喜欢
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 2020-09-04
  • 2019-11-12
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 2019-05-08
相关资源
最近更新 更多