如何对数组进行混洗或随机化,以使所得数组的元素之和在Swift 4.1中始终等于固定值?

时间:2018-10-18 23:15:54

标签: arrays swift

我正在尝试对数字数组进行混洗,然后将所得的随机数组存储在变量中。但是我希望得到的随机数组的元素总和为1。

var numbers = [1,0.5,0.25,0.125,0.0625]
var newTime = [Double]()
var x = numbers.shuffled()

for _ in 0..<x.count {
            newTime.append(x.random_element())
        }
var sum = newTime.reduce(0, +)
for _ in 0..<newTime.count {
   if sum == 1 {
             print("Final Sum: \(newTime)")
        }
   if sum > 1 {
             let rand = Int(arc4random_uniform(UInt32(newTime.count)))
             newTime.remove(at: rand)
        } else if sum < 1 {
            newTime.append(x.random_element())
        }
}    

编辑:(根据邓肯的建议)

var numbers = [1,0.5,0.25,0.125,0.0625]
var newTime = [Double]()
var x = numbers.shuffled()

for _ in 0..<x.count {
            newTime.append(x.random_element())
        }
var sum = newTime.reduce(0, +)
newTime.append(1.0 - sum)
print(newTime)

只要(1.0-sum)是一个正数,它就起作用。在这种情况下,将一个正数附加到数组中,从而使数组中所有元素的总和等于1.0。 但是,如果(1.0-sum)是负数,那么它对我不起作用,因为生成的newTime数组将具有该数组中的所有先前元素,再加上一个负数,该负数基本上总计为1.0。在这种情况下,所得的newTime = [0.125,0.25,0.0625,1.0,1.0,-1.4375]。我期望newTime = [1.0],因为其余元素的总和为1.4375,因此,我需要将它们从newTime数组中删除。

希望我能够清楚地说明事情。

1 个答案:

答案 0 :(得分:1)

您的目标很困惑,您的代码没有多大意义。您说要对数组进行混洗,但然后又说要使数组中元素的总和始终为1。数组中元素的顺序对总和没有影响。听起来您想创建一个总和为1.0的浮点值的随机数组,然后将其随机化。

那是2种不同的东西。

如果您使用的是Swift 4.2,则可以创建一个对象数组,其总和为1.0,如下所示:

var array = [Double]()

//create an array of values ranging from -2.0 to 2.0
for _ in 1...10 {
    array.append(Double(Int.random(in: -2000...2000))/1000.0)
}
let sum = array.reduce(0, +)

//Add one more value that brings the sum of the array contents to ≈ 1.0
array.append(1.0 - sum)

然后只需使用

即可对数组进行混洗
array.shuffle()

由于浮点数的限制,数组的总和可能不完全精确。 1.您可能会得到0.99999999998或1.0000000004之类的值,但是如果将总和四舍五入到小数点后三位是1.000