Kotlin中如何高效从不相交范围的并集中生成随机数?
Kotlin 标准库目前没有内置专门针对多范围并集生成随机数的专用API,但你可以基于标准库的基础能力实现完全无中间集合、内存开销为O(1)的方案,代码非常简洁:
最优实现(无内存开销,适用于任意大小的范围)
首先写一个通用的Iterable<IntRange>扩展函数:
fun Iterable<IntRange>.randomUnion(): Int { val totalCount = sumOf { it.last - it.first + 1 } var offset = (0 until totalCount).random() for (range in this) { val rangeLength = range.last - range.first + 1 if (offset < rangeLength) return range.first + offset offset -= rangeLength } throw IllegalArgumentException("Input ranges can not be empty") }
调用方式如下,完全不会生成范围对应的中间元素列表,哪怕范围大小到百万、千万级别也不会有内存问题:
// 示例:从1~10和50~100的并集取随机数 val randomNum = listOf(1..10, 50..100).randomUnion()
如果是针对LongRange,只需要把扩展函数的类型调整为Iterable<LongRange>,对应数值类型改为Long即可,逻辑完全通用。
临时简化写法(仅适用于范围数量少、单范围长度小的场景)
如果你只是临时用不想写扩展函数,也可以用标准库现有API实现,但注意这个写法还是会生成轻量的中间集合,不适合超大范围:
val randomNum = listOf(1..10, 50..100) .flatMap { range -> List(range.count()) { range } } .random() .random()
内容的提问来源于stack exchange,提问作者A.P.
相关产品推荐
相关产品推荐

