Algorithm 基于子集平面映射的Scala置换
我有排列的方法:Algorithm 基于子集平面映射的Scala置换,algorithm,scala,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
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)
}
}
}
首先,它使用一个递归调用,对列表(“a”、“b”、“c”)进行头、尾的配对:
c-零
b-c
公元前
并在零件前后排列。因此,我有三个以后的所有排列。我的下一个问题是:为什么递归调用不返回像“bc”、“cb”、“c”这样的中间语句,并在以后的三个语句中返回有效集。在每次迭代中,您必须只返回与输入列表大小相同的列表,因为您返回的排列形式是
(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
}
}
我猜你想实现你自己的,但如果你不知道
Seq
有一个permutations
方法(List
implementsSeq
),我知道Seq中的permutation方法,那只是一个组合数学的实验。你说过吗“在每次迭代中,您必须只返回与输入列表大小相同的列表”,如果在递归调用中perm
只包含单个元素(例如“c”),它必须返回list(x)+“c”,该情况如何“
,长度与输入列表长度不一致,但perm
不能只包含单个元素c
,因为此声明适用于创建perm
的递归调用!想想“归纳法证明”的法则:如果你证明了“基础”主张(对于Nil
,所有结果的大小都为0),以及“归纳步骤”(如果我们假设perm.size==xs.size
,那么迭代的结果都与lst
,这就是我所展示的),然后-声明代表所有迭代。我不认为perm
包含严格的元素计数,因为lst
在每次迭代中,我将println附加到outperm
,它是Nil
“c”,“bc”
,“cb”
。它只在不同的迭代中给出不同的大小-在同一个迭代中,perm
的所有值都具有相同的大小。是的,这是真的,您说过:“每个循环只返回与输入大小相同的值”,这是否适用于任何递归调用?