这是洗牌一套足够的方法吗?
我试图在我的应用程序中洗牌,我使用下面的代码。 这是否足够随机化甲板? 我几乎可以肯定的是只是想要另一个意见。 谢谢!
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-Yatesalgorithm的一个实现。 我从@MartinR的post中得到它可以在这里find: 什么是最好的方式来洗牌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]; }
如果[deck.cards count] <40000,你的代码应该工作得相当好,但以下更好
for (int i = [deck.cards count] - 1; i > 0 ; i--) { int randomInt1 = arc4random_uniform(i + 1); [deck.cards exchangeObjectAtIndex:randomInt1 withObjectAtIndex:i]; }
从文档:
arc4random_uniform()将返回一个小于upper_bound的均匀分布的随机数。 arc4random_uniform()build议比arc4random()%upper_bound''这样的结构更好,因为当上限不是2的幂时,它避免了“模偏置”。
这里是正确实施的Fisher-Yatesalgorithm。 是的,它将足够随机你的arrays,我用了很多次,这真是太棒了!
NSUInteger count = [deck.cards count]; if (count > 0) { for (NSUInteger i = count - 1; i > 0 ; --i) { [deck.cards exchangeObjectAtIndex:i withObjectAtIndex:arc4random_uniform(i + 1)]; } }