通过子集的flatMap进行Scala排列

时间:2016-12-27 09:41:53

标签: algorithm scala

我有制作排列的方法:

def permutations[T](lst: List[T]): List[List[T]] = lst match {
    case Nil => List(Nil)
    case x :: xs => permutations(xs) flatMap { perm =>
      (0 to xs.length) map { num =>
        (perm take num) ++ List(x) ++ (perm drop num)
      }
    }
  }

首先,它需要一个带有对头的递归调用 - 用于List的尾部(" a"," b"," c"): c - 无 b - c a - bc

并在部件之前和之后进行静音。结果,我有三个以后的所有排列。我的问题是:为什么递归调用不会返回中间语句,例如" bc"," cb"," c"然后从三个返回有效集。

1 个答案:

答案 0 :(得分:2)

好吧,在每次迭代中,您只需要返回与输入列表大小相同的列表,因为您返回(perm take num) ++ List(x) ++ (perm drop num)形式的排列,它总是包含perm中的所有元素加上x元素。

因此,递归地 - 如果每个循环仅返回与其输入相同大小的值(包括Nil的结束情况),则最终结果必须仅包含相同大小的排列。

要解决此问题,您可以将perm 不带 x添加到每个周期的结果中,但是您必须添加distinct才能摆脱重复:

def permutations[T](lst: List[T]): List[List[T]] = lst match {
  case Nil => List(Nil)
  case x :: xs => permutations(xs) flatMap { perm =>
    ((0 to xs.length) flatMap { num =>
      List(perm, (perm take num) ++ List(x) ++ (perm drop num))
    }).distinct
  }
}