关于swift:向数组添加非重复随机数

Adding non-repeating random numbers to an array

本问题已经有最佳答案,请猛点这里访问。

嗨,我正在尝试用非重复随机数创建一个数组。

我在下面写了代码numberOfAnimals,它是10,目前显示数组中有多少个数字。当我在操场上跑步时

"[6,5,1,4,7,0]"作为print语句的输出,因此总共6个数字而不是10个。为了避免这种情况,我正在减少if语句中i的值,以防数组中已经存在随机数,在这种情况下,for循环需要一个额外的循环来达到10,但仍然不起作用。

你能查出错误在哪里吗?或者再给我一个代码建议。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import UIKit

var array = [Int]()
var max : Int = 10
var numberOfAnimals : Int = 10

for var i in 0..<numberOfAnimals {

    let randomNumber : Int = Int(arc4random_uniform(UInt32(max)))

    if array.contains(randomNumber) {

        i = i - 1

    } else {

        array.append(randomNumber)

    }

}
print(array)


我建议您对@joakim danielson的答案稍作修改,如果您能负担得起额外的空间并实现一个集合-如果一个数组不重要,您也可以考虑为您的实现考虑一个集合,只要0.02美元。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var array = [Int]()
var seen = Set<Int>()
let max = 10

while array.count < max {

    let number = Int(arc4random_uniform(UInt32(max)))

    if seen.contains(number) {
        continue
    }

    array.append(number)
    seen.insert(number)
}
print(array)


如果你重复你的循环直到每一个数字被击中,你的算法最坏的运行时间是无限的。据我了解,您的问题是,您有一个具有固定大小和固定元素的数组,您希望对其进行无序排列,那么为什么不这样做呢?我在另一个线程中发现了一个很好的算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
extension MutableCollection {

    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }
        for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            let i = index(firstUnshuffled, offsetBy: d)
            swapAt(firstUnshuffled, i)
        }
    }

}

let numberOfAnimals = [1,2,3,4,5,6,7,8,9,10]
array.shuffle()
print(array)


为什么不让while循环一直持续到数组中有十个数字。

1
2
3
4
5
6
7
while array.count < 10 {
...

  if !array.contains(randomNumber) {
    array.append(randomNumber)
  }
}