我有一组称为卡片的整数[52]。每个元素包含一个代表一张牌的整数(例如,牌[0] = 5代表俱乐部的6个)。
这就是我改组数组的方式。它有效,但我正在重复。
private void shuffleCards()
{
for (int i = 0; i < cards.Length; i++)
{
int randIndex = r.Next(0, 52);
int origCard = cards[i];
cards[i] = cards[randIndex];
cards[randIndex] = origCard;
}
}
r是我在程序开头初始化的随机变量。
在测试程序时,我注意到我会得到相同的卡2或3次。显然我不能重复,他们都必须是不同的。我无法以任何方式看到这种方法如何让我重复。
如何在不重复的情况下对此数组进行洗牌?感谢。
修改
好的,事实证明,随机播放功能不是问题所在。是导致问题的deal()函数。
private void deal()
{
for (int i = 0; i < 26; i++)
{
userCards[i] = cards[i];
setUserValue(); //ignore this
}
for (int i = 26; i < 52; i++)
{
opponentCards[i - 26] = cards[i];
setOpponentValue(); //ignore this
}
}
我确信它不是随机播放功能。我将所有卡的结果打印到文本文件中,没有看到任何迭代。然而,当卡片发给用户和对手时,即当所有迭代发生时。有什么建议吗?
答案 0 :(得分:1)
有一种非常简单的算法称为Fisher Yates shuffling算法,可以在O(n)
时间和O(1)
空间复杂度中进行混洗。
使用随机函数从给定集合生成随机索引,并替换使用最后一个索引生成的随机元素。减去最后一个索引,并像其他元素一样继续。
让大小为n的数组为:arr[n]
void randomize ( int arr[], int n )
{
// Use a different seed value so that we don't get same
// result each time we run this program
srand ( time(NULL) );
// Start from the last element and swap one by one. We don't
// need to run for the first element that's why i > 0
for (int i = n-1; i > 0; i--)
{
// Pick a random index from 0 to i
int j = rand() % (i+1);
// Swap arr[i] with the element at random index
swap(&arr[i], &arr[j]);
}
}
来源:Algorithm