我想写一个应该返回整数列表的函数。整数列表大小和最大随机数将由用户定义,用户将通过函数参数。我的特殊要求是,整数列表不能多余
我使用<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body onload="startGame()">
<div style="text-align:center;width:480px;">
<button onclick="moveup()">UP</button><br><br>
<button onclick="moveleft()">LEFT</button>
<button onclick="moveright()">RIGHT</button><br><br>
<button onclick="movedown()">DOWN</button>
</div>
<p>If you click a button the red square will start moving. Click the same button many times, and it will move faster and faster.</p>
</body>
</html>
的方法:
Array
问题:有时我会通过这种方法获得重复值
我知道swift func getRandomNumbers(maxNumber: Int, listSize: Int)-> [Int]{
var randomNumbers = [Int]()
for _ in 1...listSize{
let randomNumber = Int(arc4random_uniform(UInt32(listSize)))
randomNumbers.append(randomNumber)
}
return randomNumbers
}
没有重复值。
我使用Set
的方法:
Set
问题:有时func getRandomNumbers(maxNumber: Int, listSize: Int)-> Set<Int>{
var randomNumbers = Set<Int>()
for _ in 1...listSize{
let randomNumber = Int(arc4random_uniform(UInt32(listSize)))
randomNumbers.insert(randomNumber)
}
return randomNumbers
}
大小小于用户定义的大小。
答案 0 :(得分:1)
你需要使用while count小于listSize而不是for循环,而不是你需要将maxNumber加一而不是listSize传递给arc4random_uniform:
func getRandomNumbers(maxNumber: Int, listSize: Int)-> Set<Int> {
var randomNumbers = Set<Int>()
while randomNumbers.count < listSize {
let randomNumber = Int(arc4random_uniform(UInt32(maxNumber+1)))
randomNumbers.insert(randomNumber)
}
return randomNumbers
}
getRandomNumbers(maxNumber: 10, listSize: 3) // {5, 7, 0}
答案 1 :(得分:1)
当您获得重复的随机数时会发生这种情况。您可以检查randomNumbers.count并生成随机数,直到它到达listSize,而不是生成listSize随机数。
答案 2 :(得分:1)
这里有两个问题:
您没有生成足够的数字。您需要继续生成随机数,直到您的集合足够大:
func getRandomNumbers(maxNumber: Int, listSize: Int)-> [Int] {
var randomNumbers = Set<Int>()
while randomNumbers.count < listSize {
let randomNumber = Int(arc4random_uniform(UInt32(maxNumber+1)))
randomNumbers.insert(randomNumber)
}
return randomNumbers
}
您通过将随机数放入排序集选择中来偏向您,这是非常可预测的。您应该将数字附加到数组(以保持它们的生成顺序),同时仍然并行使用集合,以实现快速重复数据删除:
func getRandomNumbers(maxNumber: Int, listSize: Int)-> [Int] {
precondition(listSize < maxNumber, "Cannot generate a list of \(listSize) unique numbers, if they all have to be less than \(maxNumber)")
var randomNumbers = (array: [Int](), set: Set<Int>())
while randomNumbers.set.count < listSize {
let randomNumber = Int(arc4random_uniform(UInt32(maxNumber+1)))
if randomNumbers.set.insert(randomNumber).inserted { // If the number is unique
randomNumbers.array.append(randomNumber) // then also add it to the arary
}
}
return randomNumbers.array
}
答案 3 :(得分:1)
这是另一种可能性。我不是声称这是最好的,但在我看来,IndexSet
可能是一个解决问题的好方法(基本上,这个想法书呆子,我必须找到答案),这就是我想出来的。
func getRandomNumbers(maxNumber: Int, listSize: Int)-> [Int]{
guard maxNumber < listSize else { return [] }
var indexSet = IndexSet(integersIn: 0...listSize)
var randomInts = [Int]()
while randomInts.count < maxNumber {
guard let currentInt = indexSet.integerLessThanOrEqualTo(Int(arc4random_uniform(UInt32(listSize)))) else {
continue
}
randomInts.append(currentInt)
indexSet.remove(currentInt)
}
return randomInts
}
我们的想法是创建一个覆盖0到请求的最大值的IndexSet
,然后从该集合中随机删除元素,直到你有足够的元素。它通过在使用集合时删除整数来避免重复。 IndexSet
实际上不是Set
,它是存储一堆唯一整数的有效方式,因此它获得了Set
的唯一性而没有实际创建{{1}包含范围内的所有整数。
答案 4 :(得分:1)
Swift 5 版本实现
extension Int {
static func getUniqueRandomNumbers(min: Int, max: Int, count: Int) -> [Int] {
var set = Set<Int>()
while set.count < count {
set.insert(Int.random(in: min...max))
}
return Array(set)
}
}
例如:
let uniqueNumbers = Int.getUniqueRandomNumbers(min: 1000, max: 1500, count: 10)
示例结果:
[1454, 1105, 1305, 1176, 1498, 1127, 1310, 1209, 1373, 1198]