You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中如何获取指定大小范围内的集合子集?

获取大小为10或更小子集的Scala函数式实现

先回顾一下你已经熟悉的基础用法:

println((1 to 25).toSet.subsets.size)    // 所有子集数量:33554432
println((1 to 25).toSet.subsets(1).size) // 大小为1的子集数量:25
println((1 to 25).toSet.subsets(10).size) // 注:实际应为组合数C(25,10)=3268760,推测是输入笔误

要实现获取所有大小≤10的子集,函数式编程的核心是用高阶函数替代显式循环,这里有两种简洁的实现方式:

方式一:用flatMap(最简洁直观)

flatMap天生适合处理“把多个集合/迭代器合并为一个”的场景,正好匹配我们遍历目标子集大小并合并结果的需求:

val originalSet = (1 to 25).toSet
// 获取所有大小从0到10的子集(若不需要空集,可改成1 to 10)
val subsetsUpTo10 = (0 to 10).flatMap(originalSet.subsets)

// 统计符合条件的子集数量
println(subsetsUpTo10.size)

解释:(0 to 10)生成了我们要覆盖的所有子集大小,flatMap会依次调用originalSet.subsets(size)获取对应大小的子集迭代器,然后自动把所有迭代器里的元素展开合并成一个Iterable[Set[Int]],全程没有显式循环,完全是函数式风格。

方式二:用foldLeft(更灵活,适合自定义累加逻辑)

如果需要在累加过程中做额外处理(比如过滤特定子集),可以用foldLeft逐步合并结果:

val originalSet = (1 to 25).toSet
val subsetsUpTo10 = (0 to 10).foldLeft(Set.empty[Set[Int]]) { (accumulator, size) =>
  accumulator ++ originalSet.subsets(size)
}

这里foldLeft从空集合开始,每次把对应大小的子集合并到累加器中,最终得到所有符合条件的子集集合。

额外优化:仅统计数量(无需生成实际子集)

如果你的需求只是统计数量而不需要生成所有子集,直接计算组合数的和效率会高得多(避免创建大量子集对象):

import scala.math.BigInt

val totalCount = (0 to 10).map(k => BigInt(25).choose(k)).sum
println(totalCount)

BigInt.choose(k)会计算从25个元素中选k个的组合数,把0到10的结果相加就是所有大小≤10的子集总数。

内容的提问来源于stack exchange,提问作者CW Holeman II

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:36:38