Scala入门者求助:生成列表元素固定位置的所有组合
解决Scala列表元素固定位置的全组合生成问题
嘿,作为Scala新手能想到这个需求真的很赞!咱们来一步步搞定这个问题~
需求分析
你要的其实是列表中每个位置都有两种选择:保留原元素,或者用*标记为不参与,所以对于长度为n的列表,总共有2^n种组合。比如List(1,1)就有2^2=4种,正好是你期望的结果。
实现思路
我们可以利用Scala集合的foldLeft和flatMap来逐步构建所有组合:
- 从一个空组合列表开始(
List(List())) - 遍历原列表的每个元素,对现有的每一种组合,分别生成两个新组合:一个添加原元素,另一个添加
* - 最终得到所有可能的组合
代码实现
def generateCombos[A](list: List[A]): List[List[Any]] = { // 初始值是包含空列表的列表,作为组合的起点 list.foldLeft(List(List.empty[Any])) { (currentCombos, elem) => // 对每个现有组合,生成两个新组合:加原元素 或 加* currentCombos.flatMap(combo => List(combo :+ elem, combo :+ '*')) } }
测试验证
咱们来跑一下你给的例子:
val input = List(1, 1) val result = generateCombos(input) // 输出结果: // List(List(1, 1), List(1, *), List(*, 1), List(*, *))
完全符合你的预期!再试个其他例子,比如List(2, 3),会得到:List(List(2, 3), List(2, *), List(*, 3), List(*, *)),也是正确的。
小补充
如果想让类型更严谨(避免Any),可以定义一个密封特质来统一原元素和*,比如:
sealed trait Element[+A] case class Included[+A](value: A) extends Element[A] case object Excluded extends Element[Nothing] def generateTypedCombos[A](list: List[A]): List[List[Element[A]]] = { list.foldLeft(List(List.empty[Element[A]])) { (acc, elem) => acc.flatMap(combo => List(combo :+ Included(elem), combo :+ Excluded)) } }
这样返回的列表元素类型都是Element[A],更符合Scala的类型安全特性,但对于新手来说,第一个简单版本已经足够好用啦~
内容的提问来源于stack exchange,提问作者Rayan
相关产品推荐
相关产品推荐

