xcode 非重复 arc4random_uniform
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10233517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Non-repeating arc4random_uniform
提问by Jens Hendar
I've been trying to get non-repeating arc4random_uniform to work for ages now for my iPhone app. Been over all the questions and answers relating to this on stackoverflow with no luck and now I'm hoping someone can help me. What I want to do is is choose 13 different random numbers between 1 and 104. I have gotten it to work to the point of it choosing 13 different numbers, but sometimes two of them are the same.
我一直试图让非重复的 arc4random_uniform 现在为我的 iPhone 应用程序工作多年。在没有运气的情况下在 stackoverflow 上解决了所有与此相关的问题和答案,现在我希望有人可以帮助我。我想要做的是在 1 到 104 之间选择 13 个不同的随机数。我已经让它工作到了它选择 13 个不同数字的程度,但有时它们中的两个是相同的。
int rand = arc4random_uniform(104);
This is what I'm doing, and then I'm using the rand to choose from an array. If it's easier to shuffle the array and then pick 13 from the top, then I'll try that, but I would need help on how to, since that seems harder.
这就是我正在做的,然后我使用 rand 从数组中进行选择。如果改组数组然后从顶部选择 13 更容易,那么我会尝试这样做,但我需要有关如何操作的帮助,因为这似乎更难。
Thankful for any advice.
感谢您的任何建议。
回答by jscs
There's no guarantee whatsoever that ar4random_uniform()
won't repeat. Think about it for a second -- you're asking it to produce a number between 0 and 103. If you do that one hundred and five times, it has no choice but to repeat one of its earlier selections. How could the function know how many times you're going to request a number?
没有任何保证ar4random_uniform()
不会重复。想一想——你要求它产生一个 0 到 103 之间的数字。如果你这样做一百零五次,它别无选择,只能重复它之前的选择之一。该函数如何知道您要请求一个号码多少次?
You will either have to check the list of numbers that you've already gotten and request a new one if it's a repeat, or shuffle the array. There should be any number of questions on SO for that. Here's one of the oldest: What's the Best Way to Shuffle an NSMutableArray?.
您要么必须检查已经获得的数字列表,如果重复,则请求一个新的数字,或者对数组进行洗牌。应该有很多关于 SO 的问题。这是最古老的方法之一:对 NSMutableArray 进行洗牌的最佳方法是什么?.
There's also quite a few questions about non-repeating random numbers: https://stackoverflow.com/search?q=%5Bobjc%5D+non-repeating+random+numbers
还有不少关于非重复随机数的问题:https: //stackoverflow.com/search?q=%5Bobjc%5D+non-repeating+random+numbers
回答by HeWhoShallNotBeNamed
You can create an NSMutableSet
and implement it like this:
您可以NSMutableSet
像这样创建并实现它:
NSMutableArray* numbers = [[NSMutableArray alloc] initWithCapacity: 13];
NSMutableSet* usedValues = [[NSMutableSet alloc] initWithCapacity: 13];
for (int i = 0; i < 13; i++) {
int randomNum = arc4random_uniform(104);
while ([usedValues containsObject: [NSNumber numberWithInt: randomNum]) {
randomNum = arc4random_uniform(104)
}
[[usedValues addObject: [NSNumber numberWithInt: randomNum];
[numbers addObject: [[NSNumber numberWithInt: randomNum];
}
回答by Tecker
Alternatively you can also create a mutable array of 105 integers each a unique one, and arc4random_uniform([arrayname count]) and then delete that same one from the array, then you'll get a random int each time without repeating (though the smaller the array gets the easier it is to predict what the next number will be, just simple probability)
或者,您也可以创建一个由 105 个整数组成的可变数组,每个数组都是唯一的,并且 arc4random_uniform([arrayname count]) 然后从数组中删除相同的一个,然后您每次都会得到一个随机整数而不重复(尽管较小的数组变得更容易预测下一个数字是什么,只是简单的概率)
回答by Kostub Deshmukh
The best algorithm that I have found for this exact question is described here:
这里描述了我为这个确切问题找到的最佳算法:
Algorithm to select a single, random combination of values?
Instead of shuffling an array of 104 elements, you just need to loop through 13 times. Here is my implementation of the algorithm in Objective C:
您只需要循环 13 次,而不是对包含 104 个元素的数组进行混洗。这是我在目标 C 中的算法实现:
// Implementation of the Floyd algorithm from Programming Pearls.
// Returns a NSSet of num_values from 0 to max_value - 1.
static NSSet* getUniqueRandomNumbers(int num_values, int max_value) {
assert(max_value >= num_values);
NSMutableSet* set = [NSMutableSet setWithCapacity:num_values];
for (int i = max_value - num_values; i < max_value; ++i) {
NSNumber* rand = [NSNumber numberWithInt:arc4random_uniform(i)];
if ([set containsObject:rand]) {
[set addObject:[NSNumber numberWithInt:i]];
} else {
[set addObject:rand];
}
}
return set;
}