集合的F#子集

时间:2018-07-12 18:20:20

标签: f#

嗨,我正在尝试编写一个函数,该函数接受一个整数列表并返回该列表的所有子集的列表。

因此,例如[5; 9; 7]不会以特定顺序返回[[5; 9; 7]; [5; 9]; [5; 7]; [9; 7]; [5]; [9]; [7]]

我一辈子都无法弄清楚该怎么做。我在互联网上看过,唯一能找到的解决方案是

module Set = 
  /// Returns all subset of a specified set. For example, for input [1;2;3],
  /// the result will be a set containing sets [1;2;3], [1;2], [1;3], [2;3]
  /// [1], [2], [3] and [].
  let rec subsets s = 
    set [ // Add current set to the set of subsets
          yield s
          // Remove each element and generate subset of 
          // that smaller set
          for e in s do
            yield! subsets (Set.remove e s) ]

// Sample usage
Set.subsets (set [1 .. 3])

但是,我想使用简单列表而不是模块集。如何使用可能使用列表推导的简单功能来做到这一点?

2 个答案:

答案 0 :(得分:4)

您需要做的就是从原始列表中删除每个元素(一次删除一个)并生成结果列表,然后对结果列表进行递归执行相同的操作:

let rec getSubLists l =
    [ yield l
      for x in l do
        let rest = l |> List.except [x]
        yield rest
        yield! getSubLists rest
    ] |> List.distinct

这应该为您提供原始列表的所有不同子列表,包括空列表。

getSubLists [1;2;3]

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

答案 1 :(得分:0)

以下函数查找列表的所有子列表:

let rec powerset (xs: 'T list) : 'T list list =
    match xs with
    | [] -> [[]]
    | h::t -> List.fold (fun ys s -> (h::s)::s::ys) [] (powerset t)

对于集合,您可以将集合转换为列表,调用此函数,然后再转换回集合列表:

let powerSet (s: Set<'T>) : Set<'T> list = 
    s
    |> Set.toList
    |> powerset
    |> List.map Set.ofList

> [0..2] |> Set.ofList |> powerSet;;
val it : Set<int> list =
  [set [0; 2]; set [2]; set [0; 1; 2]; set [1; 2]; set [0]; set []; set [0; 1];
   set [1]]