【问题标题】:Generate a Swift array of nonrepeating random numbers生成一个非重复随机数的 Swift 数组
【发布时间】:2015-03-26 09:34:42
【问题描述】:

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

  1. 设置一个空数组
  2. 生成随机数
  3. 检查数组是否为空
    一种。如果数组为空,则插入随机数
    湾。如果数组不为空,将随机数与数组中的数字进行比较
    一世。如果数字相同,重复 2
    ii.如果数字不相同,则插入随机数并重复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...
     }
    }
    

【问题讨论】:

标签: ios arrays swift random


【解决方案1】:

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

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)
        }
    }
}

【讨论】:

  • 你的 var (i) 没有被使用。
【解决方案2】:

您在方法中寻找的结构可能类似于:

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..&lt;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)
}

【讨论】:

    【解决方案3】:

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

    因此,如果您只想以随机顺序从特定数字范围(例如 0-100)中获得一个数字数组,您可以先用“正常”顺序的数字填充数组。例如 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]
    

    【讨论】:

      猜你喜欢
      • 2019-02-10
      • 2011-11-24
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      相关资源
      最近更新 更多