您在方法中寻找的结构可能类似于:
var temp: [Int] = []
while temp.count < 4 {
var randomNumber: Int
do {
randomNumber = randomInt(1, 5)
} while contains(temp, randomNumber)
temp.append(randomNumber)
}
这对于像你这样的小范围来说很好,但对于更大的范围,它会很慢,因为对于最后几个数字,你正在等待随机数精确地达到剩余的少数可能性。我刚刚尝试在操场上从 200 范围内生成,只用了 9 秒。
如果您想要随机选择一个范围内保证覆盖范围的数字,您可以通过获取该范围并将其改组来生成它,如下所示:
func shuffle<S: SequenceType>(source: S) -> [S.Generator.Element] {
var rangen = GeneratorOf { arc4random() }
let a = Array(Zip2(rangen, source))
return a.sorted { $0.0 < $1.0 }.map { $0.1 }
}
let min = 1, max = 5
shuffle(min...max)
如果你想从0..<m 范围内选择 n 个不重复的随机数,有一个特别漂亮的算法可以从该范围内生成随机数的升序序列:
func randomGeneratorOf(#n: Int, #from: Int) -> GeneratorOf<Int> {
var select = UInt32(n)
var remaining = UInt32(from)
var i = 0
return GeneratorOf {
while i < from {
if arc4random_uniform(remaining) < select {
--select
--remaining
return i++
}
else {
--remaining
++i
}
}
return nil
}
}
你可以这样使用:
let engines = [
"Duck","Emily","Gordon","Henry", "Mavis",
"Belle","James","Edward","Thomas","Toby"
]
let picks = Array(randomGeneratorOf(n: 3, from: engines.count))
for engine in PermutationGenerator(elements: engines, indices: picks) {
println(engine)
}