2013-05-29 38 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