生成 Swift 个非重复随机数数组

Generate a Swift array of nonrepeating random numbers

我想在 Swift 中生成多个不同的随机数。程序如下。

  1. 设置一个空数组
  2. 生成一个随机数
  3. 检查数组是否为空
    一个。如果数组为空,插入随机数
    b.如果数组不为空,将随机数与数组
    中的数字进行比较 一世。如果数字相同,则重复2
    二.如果数字不相同,则插入随机数并重复 2

    import UIKit 
    
    //the random number generator
    func randomInt(min: Int, max:Int) -> Int {
        return min + Int(arc4random_uniform(UInt32(max - min + 1)))
    }
    
    var temp = [Int]()
    for var i = 0; i<4; i++ {
      var randomNumber = randomInt(1, 5)
      if temp.isEmpty{
        temp.append(randomNumber)
      } else {
      //I don't know how to continue...
     }
    }
    

如果你使用你的方法,问题是,你每次都会创建一个新的随机数。所以你可能有 4 次相同的随机数,所以你的数组将只有一个元素。

因此,如果您只想从特定范围内的数字(例如 0-100)中随机排列一个数字数组,您可以先用 [=22= 中的数字填充一个数组] 命令。例如 for 循环等:

var min = 1
var max = 5
for var i = min; i<= max; i++ {
    temp.append(i)
}

之后,你可以使用shuffle方法对数组的所有元素进行shuffle方法来自this answer:

func shuffle<C: MutableCollectionType where C.Index == Int>(var list: C) -> C {
    let count = countElements(list)
    for i in 0..<(count - 1) {
        let j = Int(arc4random_uniform(UInt32(count - i))) + i
        swap(&list[i], &list[j])
    }
    return list
}

在你可以做类似的事情之后:

shuffle(temp)        // e.g., [3, 1, 2, 4, 5]

您正在寻找的结构可能类似于:

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 { [=11=].0 < .0 }.map { [=11=].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)
}

以下是我的建议。 我喜欢这种方式,因为它又短又简单:)

let totalCount: Int = 150 //Any number you asssign
var randomNumArray: [Int] = []
var i = 0
while randomNumArray.count < totalCount {
    i++
    let rand = Int(arc4random_uniform(UInt32(totalCount)))
    for(var ii = 0; ii < totalCount; ii++){
        if randomNumArray.contains(rand){
            print("do nothing")
        } else {
            randomNumArray.append(rand)
        }
    }
}