如何在Swift中生成一个随机数而不重复前一个随机数?

bma*_*iel 11 swift

我对Swift和编程逻辑都很陌生,所以请耐心等待

如何在Swift中生成0到9之间的随机数,而不重复上一次生成的数字?因为相同的数字不会连续出现两次.

ham*_*obi 17

我的解决方案,我认为它很容易理解

var nums = [0,1,2,3,4,5,6,7,8,9]

while nums.count > 0 {

    // random key from array
    let arrayKey = Int(arc4random_uniform(UInt32(nums.count)))

    // your random number
    let randNum = nums[arrayKey] 

    // make sure the number isnt repeated
    nums.removeAtIndex(arrayKey)
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*uch 11

将先前生成的数字存储在变量中,并将生成的数字与之前的数字进行比较.如果匹配则生成新的随机数.重复生成新数字,直到它们不匹配.

var previousNumber: UInt32? // used in randomNumber() 

func randomNumber() -> UInt32 {
    var randomNumber = arc4random_uniform(10)
    while previousNumber == randomNumber {
        randomNumber = arc4random_uniform(10)
    }
    previousNumber = randomNumber
    return randomNumber
}
Run Code Online (Sandbox Code Playgroud)

  • ... 理论上,任何对 `randomNumber()` 的调用都不能保证在 `while` 循环中给定的非无限次数的允许迭代中终止(即使它在实践中会很快:) )。对于确定性的解决方案(在调用 `randomNumber()` 时编写程序流程),[请参阅下面的 vacawama:s 聪明答案](http://stackoverflow.com/a/27548748/4573247)。 (2认同)

vac*_*ama 7

Swift 5 更新

这是一个很好的技巧,可以从之前选择的数字中平等地选择。

您有 10 个号码,但您只想从 9 个号码中进行选择(0 到 9,但不包括前一个号码)。如果将范围减少 1,则可以从 9 个随机数中进行选择,然后将重复的数字替换为范围的前一个顶部数字。这样,您每次只需生成一个随机数即可获得一致性。

这可以实现为Int.random(in:excluding:)您传递想要的值exclude

extension Int {
    static func random(in range: ClosedRange<Int>, excluding x: Int) -> Int {
        if range.contains(x) {
            let r = Int.random(in: Range(uncheckedBounds: (range.lowerBound, range.upperBound)))
            return r == x ? range.upperBound : r
        } else {
            return Int.random(in: range)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

例子:

// Generate 30 numbers in the range 1...3 without repeating the
// previous number  
var r = Int.random(in: 1...3)
for _ in 1...30 {
    r = Int.random(in: 1...3, excluding: r)
    print(r, terminator: " ")
}
print()
Run Code Online (Sandbox Code Playgroud)

1 3 2 1 2 1 3 2 1 3 1 3 2 3 1 2 3 2 1 3 2 1 3 1 2 3 2 1 2 1 3 2 3 2 1 3 1 2 1 2


上一个答案:

var previousNumber = arc4random_uniform(10)   // seed the previous number

func randomNumber() -> UInt32 {
    var randomNumber = arc4random_uniform(9)  // generate 0...8
    if randomNumber == previousNumber {
        randomNumber = 9
    }
    previousNumber = randomNumber
    return randomNumber
}
Run Code Online (Sandbox Code Playgroud)

  • 奇怪的是,撇开数组改组方法不谈,这是唯一一个保证在该线程的答案中“终止”的一次随机数方法(“终止”并不是真正有趣的术语这里是非常终止确定性的解决方案,但是在接受的答案中使用了蛮力循环方法)。所以我留下这个额外的评论,指出我相信这应该是公认的答案。 (2认同)

Sam*_*fes 5

最简单的方法是使用 repeat/while:

let current = ...
var next: Int

repeat {
    next = Int(arc4random_uniform(9))
} while current == next

// Use `next`
Run Code Online (Sandbox Code Playgroud)