【发布时间】:2014-04-30 16:38:46
【问题描述】:
我正在尝试在我的应用程序中洗牌,并使用以下代码。这会让套牌充分随机化吗?我几乎可以肯定只是想要另一种意见。谢谢!
for (int i = 0; i < 40000; i++) {
int randomInt1 = arc4random() % [deck.cards count];
int randomInt2 = arc4random() % [deck.cards count];
[deck.cards exchangeObjectAtIndex:randomInt1 withObjectAtIndex:randomInt2];
编辑:如果有人想知道或将来应该遇到这个问题。这就是我用来洗牌的方法,它是 Fisher-Yates 算法的一种实现。我从下面建议的@MartinR 帖子中得到它,可以在这里找到:What's the Best Way to Shuffle an NSMutableArray?
NSUInteger count = [deck.cards count];
for (uint i = 0; i < count; ++i)
{
// Select a random element between i and end of array to swap with.
int nElements = count - i;
int n = arc4random_uniform(nElements) + i;
[deck.cards exchangeObjectAtIndex:i withObjectAtIndex:n];
}
【问题讨论】:
-
两项改进 - 1) 将
[deck.cards count]存储在循环之前的变量中,这样您就不需要调用该方法 80,000 次。 2) 使用arc4random_uniform(count)而不是arc4random与模数。 -
“这会让牌组充分随机化吗?” 对于概率论专家来说,这更像是一个数学问题。 - 例如,可以在此处找到用于 NSArray 的 Fisher-Yates 算法的实现:What's the Best Way to Shuffle an NSMutableArray?。
-
@Rob 我的意思是
[deck.cards count]应该在循环之前存储在一个变量中,然后在循环中,应该使用该变量。这样可以节省 80,000 次方法调用。 -
@Rob,是的,将循环从 40,000 减少到 52 是一个更好的改进。 :)
标签: ios objective-c algorithm shuffle