我想用纯粹的swift随机化10,000个布尔值并获得所有那些真实的总和。
答案 0 :(得分:3)
可以使用reduce()
函数方便地计算总和:
/// Return the result of repeatedly calling `combine` with an
/// accumulated value initialized to `initial` and each element of
/// `sequence`, in turn.
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U
如果您只对这笔款项感兴趣:
let sum = reduce(0 ..< 10000, 0) { (sum, _) in sum + Int(arc4random_uniform(2)) }
如果你需要Bool数组和总和:
let bools = map (0 ..< 10000) { _ in arc4random_uniform(2) == 1 }
let sum = reduce(bools, 0) { $0 + Int($1) }
更新:正如Zaph在下面建议的那样,应该使用全部32位
arc4random...
函数减少函数调用次数。这将是
let numberOfInt32 = 10000 / 32
let remainingBits = 10000 % 32
let sum = reduce(0 ..< numberOfInt32, 0) { (sum, _) in sum + NumberOfSetBits(arc4random()) }
+ NumberOfSetBits(arc4random_uniform(UInt32(1 << remainingBits)))
其中NumberOfSetBits()
计算设置位数并且是a
https://stackoverflow.com/a/109025/1187415到Swift的翻译:
func NumberOfSetBits(var i : UInt32) -> Int {
i = i - ((i >> 1) & 0x55555555)
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
return Int((((i + (i >> 4)) & 0x0F0F0F0F) &* 0x01010101) >> 24)
}
(另见Rikkle's answer 这是在平均时间发布...)
答案 1 :(得分:2)
如果你不需要保存你的布尔和
var sum = 0
for i in 1...10000{
if(arc4random_uniform(2) == 1)
sum++
}
如果你想保存它们
var sum = 0
var boolArrays = []
for i in 1...10000{
if(arc4random_uniform(2) == 1){
sum++
boolArray.addObject(true)
}
else{
boolArray.addObject(false)
}
}
答案 2 :(得分:2)
我建议在10,000/8字节数上使用arc4random_buf
,然后应用横向加法(或&#34;汉明重量&#34;)来总结该系列字节中的所有位,一次一个int(32位)。有关汉明重量的良好伪代码,请参阅https://stackoverflow.com/a/109025/1401029。
这应该比包含随机函数的任何循环结构明显更快更干净。
答案 3 :(得分:1)
arc4random_uniform()将返回均匀分布的随机数 小于upper_bound。
var countTrue : Int = 0
var countFalse : Int = 0
for i in 1 ... 10000 {
if (arc4random_uniform(2) == 1) {
countTrue++
} else {
countFalse++
}
}
NSLog("count true: \(countTrue), count false: \(countFalse)")
答案 4 :(得分:0)
如果您不需要实际的布尔值,则总和会有N=10000
和p=1/2
的二项分布。对于那么大的N,它与高斯平均值N*p
和方差N*p*(1-p)
(对应于标准偏差50)几乎无法区分,四舍五入到最近整数。您可以使用Box-Muller方法生成标准法线,并按如下方式进行缩放:
import Cocoa
let uniform_denom = UInt32(RAND_MAX) + 1
func u0_1() -> Double {
var num = arc4random_uniform(uniform_denom)
return Double(num) / Double(uniform_denom)
}
func gaussian() -> (Double, Double) {
var d = sqrt(-2.0 * log(u0_1()))
var theta = 2.0 * M_PI * u0_1()
return (d * cos(theta), d * sin(theta)) // 2-tuple of std normals
}
var sum = 5000 + Int(round(50.0 * gaussian().0)) // scale to mean = 5000, std-dev = 50