2013-05-29 31 views
1

我想找到Powerset的F#查找Powerset的

幂[1; 2; 3] = = [[]; [3]; [2]; [2; 3]; [1]; [1; 3]; [1; 2]; [1; 2; 3]

let rec powerset = function 
    | [] -> [] 
    | x::xs -> List.map (fun ys -> xs) xs::powerset (xs) 

我有代码的麻烦,这就是我的输出貌似现在。

val it:int list list list = [[[2; 3]; [2; 3]]; [[3]]; []]

+0

的可能重复[生成幂懒洋洋地(http://stackoverflow.com/questions/8164364/generate-powerset-lazily) –

+0

如果你看看在你提供的链接上,你会看到问题是针对一系列的集合。我的问题是一个列表的权力集。 –

+0

@MikeJohn您的问题没有具体地询问F#3.0的特性,或者从脚本的角度来看如何使用F#(即在'* .fsx'文件中编写shell脚本),这就是为什么我删除了标签。是否有什么特别的理由让你认为他们应该适用? –

回答

3

其他人已经指出链接使用序列表达式并且懒惰地枚举集合。这就是我如何可以解决这个问题(注意,没有任何关于使用for内部序列理解不纯或无功能 - 它只是一个产生结果的顺序方式):

let rec powerset s = seq { 
    match s with 
    | [] -> yield [] 
    | h::t -> for x in powerset t do yield! [x; h::x] } 

那说,这可能是很容易转换成代码,返回一个列表,并使用高阶函数:

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

幂集空集是一组与单个元素[](注意,这是错误的程式码中)。要生成x::xs的powerset,我们首先生成xs的powerset,然后为生成的powerset的每个单元返回两个集合 - 一个是子集,另一个是添加了x元素的子集。 (这是使用List.collect这就好比打电话List.map其次List.concat完成。)

+0

在F#中表现如何?从C#开始,我一直认为它是在powerset中的一个foreach。 –

+0

如果你来自C#,那么你可以把'seq {..}'看作是一个迭代器方法,'yield'对应'yield return'('for'的意思与foreach'相同,但里面迭代器块,它只是生成元素 - 没有做任何突变) –

+0

你可以展开我试过| x :: xs - > List.map(List.concat(fun ss - > [ss; x :: ss]))(powerset xs);; ,并在查找b列表时获取' - > b列表。 – SuperCell