以下函数返回集合(列表)的powerset。
let rec powerset = function
| [] -> [[]]
| x::xs -> List.collect (fun sub -> [sub; x::sub]) (powerset xs)
我不明白为什么它确实有效。我理解递归。我也理解List.collect是如何工作的。我知道递归将继续,直到powerset的实例返回[[]]。但是,我尝试在该点之后跟踪返回的值,并且我从未获得完整的功率集。
答案 0 :(得分:7)
计算功率集的算法如下:
让我们调用原始集(又名“输入”)A
。让我们从该集合中挑选一个项目,称之为x
。现在,A
(称之为P(A)
)的powerset是A
的所有子集的集合。我们可以将A
的所有子集视为由两个组组成:包含x
的子集和不包含x
的子集。很容易看出,不包含x
的子集都是A - x
的所有可能子集(A
除x
除外):
all subsets of A that don't include x = P(A-x)
我们如何获得做包含A
的{{1}}的所有子集?通过将所有不包含x
并将x
添加到每个内容中的内容!
x
现在我们只需要将两者结合起来,我们自己 all subsets of A that include x = { for each S in P(A-x) : S+x }
:
P(A)
这是代码示例中的最后一行:它通过调用 P(A) = P(A-x) + { for each S in P(A-x) : S+x }
计算P(A-x)
,然后针对每个子集,将powerset xs
粘贴到其上,并且包括子集本身。