如何使它在arc4random()集中随机生成的数字永远不会重复。例如,在arc4random(100)中选择1,它将永远不会再次出现。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var card: UIImageView!
@IBOutlet weak var nextButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func nextCardTapped(sender: UIButton) {
//Edit number of cards here for the random card to show up
var randomCard = arc4random_uniform(100)
// Edit number of cards here for the random card to show up
var randomCardString:String = String(format: "card%i", randomCard)
self.card.image = UIImage(named: randomCardString)
答案 0 :(得分:1)
您所做的不是生成随机数,而是以随机顺序显示一组数字。
有一种非常简单的算法(也很快)称为Fisher-Yates shuffle。它随机地随机播放一个数组。唯一的缺点是它意味着数组中的任何数字都不能在它开始的地方。 (这可能是也可能不是你的情况下的缺点)。
无论如何,你应该创建你的数字数组。 1-300,然后将它们洗牌。
然后,当你迭代数组时,你将得到完整的300个数字,没有任何重复,每次都是随机顺序。
这是我使用的代码。 (请记住,凌晨3点,我累了,但我必须这样做。)
import UIKit
var numbers: [Int] = []
for number in 1...52 {
numbers.append(number)
}
for i in 0..<(numbers.count - 1) {
let j = Int(arc4random_uniform(UInt32(numbers.count - i))) + i
swap(&numbers[i], &numbers[j])
}
println(numbers)
可能有一种更简洁的方式来编写它。
编辑了这个功能,因为我没有工作。改编自this answer.
答案 1 :(得分:0)
您是要生成这些数字中的一些,还是很多?
如果您只生成一些,那么保留已经收到的列表可能是值得的,并且每当您再次获得其中一个时再次尝试。有点像...
NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
...
randomCard = arc4random_uniform(100);
while ([uniqueNumbers containsObject:[NSNumber numberWithInt:randomCard]]) {
// try again
randomCard = arc4random_uniform(100);
}
[uniqueNumbers addObject:[NSNumber numberWithInt:r]];
如果您打算以这种方式生成许多随机数,那么它将变得非常低效。例如,在第99个数字上,您将重复循环,直到您最终得到列表中已有的2个数字中的一个。如果你想生成很多数字,那么用它中的所有数字(1-100)创建一个集合(数组,堆栈等)可能会更有效率并将其洗牌。然后你可以一次将它们从顶部弹出。
NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
// build list
for(int i = 1; i <= 100; i = i + 1)
{
[uniqueNumbers addObject:[NSNumber numberWithInt:i]];
}
// shuffle list
for(int i = 0; i < 100; i = i + 1)
{
int n = arc4random() % 100;
[uniqueNumbers exchangeObjectAtIndex:i withObjectAtIndex:n];
}
答案 2 :(得分:0)
在NSMutableArray上添加以下类别(这是修改过的Fisher-Yates shuffle):
- (void) shuffle
{
for (NSInteger i = [self count] - 1; i > 0; --i)
{
[self exchangeObjectAtIndex:arc4random() % (i+1) withObjectAtIndex: i];
}
}
按顺序生成数字范围(例如,1-300)并将它们放在NSMutableArray中(作为NSNumber)。然后,使用上面的shuffle方法。
然后,从NSMutableArray(索引0-299)顺序提取结果。您将随机抽取数字而无需替换,我认为这就是您所追求的。
答案 3 :(得分:-3)
Xcode 8•Swift 3
extension Array {
var shuffled: Array {
var elements = self
return elements.shuffle()
}
@discardableResult
mutating func shuffle() -> Array {
indices.dropLast().forEach { a in
guard case let b = Int(arc4random_uniform(UInt32(count - a))) + a, b != a else { return }
swap(&self[a], &self[b])
}
return self
}
}
使用
let numbers = Array(1...100)
let shuffled = numbers.shuffled // [5, 60, 15, 13, 94, 70, 17, 80, 95, 11, 76, 55, 96, 45, 1, 4, 23, 97, 48, 21, 47, 38, 51, 64, 59, 44, 19, 79, 98, 61, 35, 67, 49, 71, 83, 82, 54, 69, 36, 100, 73, 99, 93, 6, 62, 91, 24, 32, 10, 31, 41, 84, 46, 72, 12, 87, 20, 65, 43, 22, 85, 68, 86, 89, 88, 58, 33, 18, 30, 63, 52, 90, 57, 14, 16, 81, 2, 29, 37, 8, 50, 78, 9, 66, 3, 7, 77, 53, 39, 56, 28, 42, 25, 27, 34, 92, 26, 74, 75, 40]
let get10randomNumbers = numbers.shuffled.prefix(10) // [71, 23, 33, 48, 73, 81, 75, 18, 19, 67]