F#Powerset功能

时间:2016-09-27 01:11:12

标签: recursion f# powerset

以下函数返回集合(列表)的powerset。

let rec powerset = function
  | [] -> [[]]
  | x::xs -> List.collect (fun sub -> [sub; x::sub]) (powerset xs)

我不明白为什么它确实有效。我理解递归。我也理解List.collect是如何工作的。我知道递归将继续,直到powerset的实例返回[[]]。但是,我尝试在该点之后跟踪返回的值,并且我从未获得完整的功率集。

1 个答案:

答案 0 :(得分:7)

计算功率集的算法如下:

让我们调用原始集(又名“输入”)A。让我们从该集合中挑选一个项目,称之为x。现在,A(称之为P(A))的powerset是A的所有子集的集合。我们可以将A的所有子集视为由两个组组成:包含x的子集和不包含x的子集。很容易看出,不包含x的子集都是A - x的所有可能子集(Ax除外):

  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粘贴到其上,并且包括子集本身。