【问题标题】:Combining list functions组合列表函数
【发布时间】:2015-03-16 08:04:08
【问题描述】:

下面的函数计算列表元素的可能组合。

不返回列表中相同的元素,只返回唯一元素:

def combinations[T](l: List[T]): List[(T,T)] = l match {
    case Nil => Nil
    case h::Nil => Nil
    case h::t => t.map(x=>(h,x)) ++ combinations(t)
}

List(1,2,3) 返回 List((1,2),(1,3),(2,3))

这个解决方案(不是我的)很优雅,但我想知道它背后的直觉。代码中是否有我不知道的列表元素的通用属性?我知道为什么这个解决方案有效,但我不确定如何得到这个解决方案?

【问题讨论】:

  • 问题是什么?解释一下为什么会这样?
  • @0__ 请查看更新

标签: scala


【解决方案1】:

当您考虑如何手动构建所有组合时,实际上非常直观。例如,以List(1, 2, 3, 4) 为例。为了有条不紊地创建所有组合,我将取列表1 中的第一个元素,然后将其与所有剩余元素组合。

(1, 2), (1, 3), (1, 4)

这些是包含1 的所有可能组合。现在让我们找出所有包含2 的组合,但我们不需要包括那些包含1 的组合,因为我们已经有了它们。这意味着我们将使用列表中剩余元素的组合。

(2, 3), (3, 4)

然后用3:

(3, 4)

你看到模式了吗?我们取列表的第一个元素,然后将其与列表的所有剩余元素(尾部)配对。这就是这部分代码:

case h :: t => t.map(x => (h, x))
 //  1 :: List(2, 3, 4) => List((1, 2), (1, 3), (1, 4))

然后我们移动到列表的下一个元素,并做同样的事情。这就是递归步骤:++ combinations(t),并将结果与​​++ 聚合。

如果我们从1开始,那么在幕后第一个递归调用是combinations(List(2, 3, 4)),我们重复这个逻辑:

case h :: t => t.map(x => (h, x))
 //  2 :: List(3, 4) => List((2, 3), (3, 4))

最后:

case h :: t => t.map(x => (h, x))
 //  3 :: List(4) => List((3, 4))

所以我们和List((1, 2), (1, 3), (1, 4)) ++ List((2, 3), (3, 4)) ++ List((3, 4))

当然还有其他零个或一个元素的情况,不能产生更多的组合:

case Nil => Nil
case h :: Nil => Nil

正如@0__ 所说,h :: Nil 确实可以由h :: t 处理,因为我们将拥有这个:

case h :: t => t.map(x => (h, x)) ++ combinations(t)
//        ^ Nil    ^ Nil maps to Nil          ^ Will hit the first case on the next call, which is also Nil

【讨论】:

    【解决方案2】:

    使用List 定义函数式/递归解决方案时,最简单的方法是涵盖发生的基本情况。然后定义部分解决方案并将它们相加。

    您需要输出中的元素对,因此您首先要弄清楚对于空列表 (Nil) 或仅包含单个元素 (h :: Nil) 的列表没有部分解决方案,因此这些两个案例的结果为Nil。最后一种情况是你有一个头部元素h 和一个非空的尾部。因此,使用 map 函数生成所有带有每个尾部元素的 h 对,并递归地重复尾部。

    请注意,从技术上讲,中间情况是无关紧要的。以下就足够了:

    def combinations[A](xs: List[A]): List[(A, A)] = xs match {
      case Nil => Nil
      case h :: t => t.map(h -> _) ++ combinations(t)
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-21
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2022-01-05
      相关资源
      最近更新 更多