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

Scala中实现两同长度列表同位元素交换的所有可能结果

优雅实现同位元素交换的所有可能结果

这问题正好适合用Scala的函数式风格来解决,完全可以用不可变列表和yield生成器来实现,不用传统的可变循环。咱们一步步来拆解思路:

核心思路

每个位置上有两种选择:不交换(保留a和b的原元素)或者交换(把a的元素放到b对应位置,b的放到a对应位置)。对于长度为n的列表,总共有2^n种可能的组合——这正好对应从0到2^n - 1的所有整数,每个整数的二进制位可以看作一个“交换掩码”:某一位为1表示对应位置要交换,为0则不交换。

代码实现

我们可以用Scala的for推导式(配合yield)来遍历所有掩码,生成对应的交换结果:

val a = List(1, 2, 3)
val b = List(4, 5, 6)
val listLength = a.length

// 生成所有可能的交换结果
val allSwaps = for {
  // 生成从0到2^n - 1的所有掩码值
  mask <- 0 until (1 << listLength)
  // 对每个位置,根据掩码决定是否交换元素对
  swappedPairs = (a zip b).zipWithIndex.map { case ((aElem, bElem), idx) =>
    if ((mask & (1 << idx)) != 0) (bElem, aElem) else (aElem, bElem)
  }
  // 将处理后的元素对拆分为新的a和b列表
  (newA, newB) = swappedPairs.unzip
} yield (newA, newB)

// 转成List类型(如果需要的话)
val resultList = allSwaps.toList

代码解释

  1. 掩码生成:1 << listLength计算的是2^listLength,所以0 until (1 << listLength)会生成所有可能的掩码值,覆盖每一种交换组合。
  2. 元素对处理:(a zip b).zipWithIndex把两个列表的同位元素配对,同时带上它们的索引。然后根据掩码的对应位判断是否交换该位置的元素:mask & (1 << idx)会检查掩码的第idx位是否为1,是则交换,否则保持原样。
  3. 拆分列表:swappedPairs.unzip把处理后的元素对列表拆分成两个新列表——newA和newB,正好是我们需要的一组结果。

验证结果

运行这段代码后,resultList会和你给出的示例完全一致:

List(
  (List(1,2,3), List(4,5,6)),
  (List(1,2,6), List(4,5,3)),
  (List(1,5,3), List(4,2,6)),
  (List(1,5,6), List(4,2,3)),
  (List(4,2,3), List(1,5,6)),
  (List(4,2,6), List(1,5,3)),
  (List(4,5,3), List(1,2,6)),
  (List(4,5,6), List(1,2,3))
)

这个方案全程使用不可变数据结构,完全依赖函数式的推导式生成结果,完美符合你的需求~

内容的提问来源于stack exchange,提问作者Meiko Rachimow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:05:35