用于递归生成器的表达式

时间:2016-07-20 19:35:08

标签: scala recursion

在下面的3个代码变体中,For Expression产生完全不同的输出。递归生成器似乎来自实数值(A,B,C),但在下面函数的version2和version3中,yield输出中没有字母。是什么原因?

def permuteV1(coll:List[Char]) : List[List[Char]] = {
  if (coll.isEmpty) List(List())
  else {
    for {
      pos <- coll.indices.toList
      elem <- permuteV1(coll.filter(_ != coll(pos)))
    } yield coll(pos) :: elem
  }
}
permuteV1("ABC".toList)
//res1: List[List[Char]] = List(List(A, B, C), List(A, C, B), List(B, A, C), List(B, C, A), List(C, A, B), List(C, B, A))


def permuteV2(coll:List[Char]) : List[List[Char]] = {
  if (coll.isEmpty) List(List())
  else {
    for {
      pos <- coll.indices.toList
      elem <- permuteV2(coll.filter(_ != coll(pos)))
    } yield elem
  }
}
permuteV2("ABC".toList)
//res2: List[List[Char]] = List(List(), List(), List(), List(), List(), List())


def permuteV3(coll:List[Char]) : List[List[Char]] = {
  if (coll.isEmpty) List(List())
  else {
    for {
      pos <- coll.indices.toList
      elem <- permuteV3(coll.filter(_ != coll(pos)))
    } yield '-' :: elem
  }
}
permuteV3("ABC".toList)
//res3: List[List[Char]] = List(List(-, -, -), List(-, -, -), List(-, -, -), List(-, -, -), List(-, -, -), List(-, -, -))

2 个答案:

答案 0 :(得分:1)

在所有三个示例中,elem为空List()。当您完成递归时,您将看到它是唯一可能的结果。

在第一种情况下,您将有意义的值预先添加到空elem。这些值保存在堆栈中,并在递归到达结束并且堆栈展开时收集。

获得相同结果的另一种方法:"ABC".toList.permutations.toList

答案 1 :(得分:0)

让我们从最后一个片段开始,因为它更明显。

你唯一添加到列表中的是' - ',所以,如果结果中包含其他任何内容,那会很奇怪吗?

现在,通过类似的推理,在第二个例子中,你从不添加任何列表,因此,结果只能包含一个空列表。

第一个有效......好吧,因为它确实会在结果中添加数据:)