生成集合中的所有"唯一"子集(不是powerset)

ska*_*tek 7 ruby erlang set subset powerset

假设我们有一个S包含几个子集的Set :

- [a,b,c]
- [a,b]
- [c]
- [d,e,f]
- [d,f]
- [e]
Run Code Online (Sandbox Code Playgroud)

我们还要说S包含六个独特的元素:a, b, c, d, ef.

我们怎样才能找到S包含每一个独特元素的所有可能子集S

函数/方法的结果应该是这样的:

  1. [[a,b,c], [d,e,f]];
  2. [[a,b,c], [d,f], [e]];
  3. [[a,b], [c], [d,e,f]];
  4. [[a,b], [c], [d,f], [e]].

有没有最佳实践或任何标准方法来实现这一目标?

我将非常感谢伪代码,Ruby或Erlang示例.

Fre*_*ung 3

听起来您正在寻找的是集合/数组的分区。

执行此操作的一种方法是递归:

  • 1 元素数组 [x] 仅有一个分区
  • 如果 x 是 x = [head] + tail 形式的数组,则 x 的分区是通过获取 tail 的每个分区并向每个可能的分区添加 head 来生成的。例如,如果我们生成 [3,2,1] 的分区,那么从 [2,1] 的分区 [[2,1]] 中,我们可以将 3 添加到 [2,1] 或作为单独的元素,这为我们提供了 [1,2,3] 的 5 个分区中的 2 个分区 [[3,2,1] 或 [[2,1], [3]]

Ruby 实现看起来有点像

def partitions(x)
  if x.length == 1
   [[x]]
  else
    head, tail = x[0], x[1, x.length-1]
    partitions(tail).inject([]) do |result, tail_partition|
      result + partitions_by_adding_element(tail_partition, head)
    end
  end
end

def partitions_by_adding_element(partition, element)
  (0..partition.length).collect do |index_to_add_at|
    new_partition = partition.dup
    new_partition[index_to_add_at] = (new_partition[index_to_add_at] || []) + [element]
    new_partition
  end
end
Run Code Online (Sandbox Code Playgroud)