A.P*_*.P. 5 random range kotlin
我想从 Kotlin 中的范围并集生成随机数。我知道我可以做类似的事情
((1..10) + (50..100)).random()
Run Code Online (Sandbox Code Playgroud)
但不幸的是,这会创建一个中间列表,当范围很大时,它可能会相当昂贵。
我知道我可以编写一个自定义函数来随机选择一个范围,其权重基于其宽度,然后从该范围中随机选择一个元素,但我想知道是否有更干净的方法来使用 Kotlin 内置函数来实现此目的。
假设您的范围不重叠且已排序,如果没有,您可以进行一些预处理来合并和排序。
这涉及到一个算法选择:
对于最后一种算法,想象有一个所有可用数字的排序列表,然后可以将该列表划分为您的范围。因此,无需真正创建此列表,只需计算 range 相对于此列表的位置即可。当您在此列表中找到一个位置并想知道它位于哪个范围时,请执行二分搜索。
fun random(ranges: Array<IntRange>): Int {
// preparation
val positions = ranges.map {
it.last - it.first + 1
}.runningFold(0) { sum, item -> sum + item }
// generation
val randomPos = Random.nextInt(positions[ranges.size])
val found = positions.binarySearch(randomPos)
// binarySearch may return an "insertion point" in negative
val range = if (found < 0) -(found + 1) - 1 else found
return ranges[range].first + randomPos - positions[range]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
502 次 |
| 最近记录: |