以下是根据此处的实现生成所有排列的简单代码:All permutations of a list
let concatElement element sequence =
seq {
yield element
yield! sequence
}
let rec permute (choices : 'a seq)=
seq {
if Seq.isEmpty choices then
yield Seq.empty
else
for choice in choices do
let remaining = choices |> Seq.where (fun el -> el <> choice)
yield concatElement choice (permute remaining)
}
我收到编译时错误“在"yield concatElement choice (permute remaining)"
这里有什么问题?
答案 0 :(得分:4)
您尝试yield
'a seq
作为类型为'a seq
的序列的单个元素。要使其工作,那么'a
必须与'a seq
的类型相同,依此类推,因此类型为“无限” - 您必须无限地嵌套它们才能“工作”
我在你的回答中看到你认识到你必须以某种方式遍历序列元素。您可以使用for .. in
语法进行迭代,或者F#为您提供实际执行此操作的yield!
运算符。本着这种精神,你的回答可以写成
let rec permute (choices : 'a seq) (permBuilder: 'a seq) : seq<seq<'a>>= seq {
if Seq.isEmpty choices then
yield permBuilder
else
for choice in choices do
let remaining = choices |> Seq.where (fun el -> el <> choice)
let newBuilder = concatElement choice permBuilder
yield! permute remaining newBuilder }
或者,或者,我们可以使用Seq.collect
函数为我们自动收集一系列序列(序列!),我们留下了很好的函数式代码,没有显式的迭代器:
let prepend element sequence = seq { yield element; yield! sequence }
let rec permute input =
if Seq.length input <= 1 then Seq.singleton input
else
let without element = Seq.where ((<>) element) input
let permutations element = permute (without element) |> Seq.map (prepend element)
Seq.collect permutations input
要考虑的事情:如果你有两个不同的元素会发生什么?例如,如果您尝试获取[1; 1; 2]
的排列,会发生什么?你当前的方法无法妥善处理 - 即使你改进了without
关闭,你也会得到重复的答案。
答案 1 :(得分:1)
我想我明白了
let concatElement element sequence =
seq {
yield element
yield! sequence
}
let rec permute (choices : 'a seq) (permBuilder: 'a seq) : seq<seq<'a>>=
seq {
if Seq.isEmpty choices then
yield permBuilder
else
for choice in choices do
let remaining = choices |> Seq.where (fun el -> el <> choice)
let newBuilder = concatElement choice permBuilder
for perm in permute remaining newBuilder do
yield perm
正如李已经评论过的那样,我试图连续seq&lt;'a&gt;用seq&lt; SEQ&LT;'一&GT;取代。我的代码缺少排列循环。