如何生成给定集的幂集?

时间:2014-06-23 12:28:30

标签: algorithm math powerset

我正在接受采访,我在“数学”类别下在网上偶然发现了这个问题。

生成给定集的幂集:

int A[] = {1,2,3,4,5};  
int N = 5; 
int Total = 1 << N;
for ( int i = 0; i < Total; i++ ) { 
 for ( int j = 0; j < N; j++) {
  if ( (i >> j) & 1 ) 
      cout << A[j]; 
   } 
 cout <<endl;

 }

我不想要一个明确的答案。我只想澄清和提示如何解决这个问题。

我检查了谷歌上的电源设置算法,我仍然不明白如何解决这个问题。

此外,有人可以重申问题所要求的内容。

谢谢。

8 个答案:

答案 0 :(得分:19)

Power set of a set A is the set of all of the subsets of A.

这不是世界上最友好的定义,但一个例子会有所帮助:

EG。对于{1, 2},子集为:{}, {1}, {2}, {1, 2}

因此,权力集是{{}, {1}, {2}, {1, 2}}

<小时/> 要生成幂集,请观察如何创建子集:逐个转到每个元素,然后保留或忽略它。

让这个决定用一点(1/0)表示。

因此,要生成{1},您需要选择1并放弃2(10)。

在类似的行上,您可以为所有子集写一个位向量:

  • {} - &gt; 00
    {1} - &gt; 10个
    {2} - &gt; 01
    {1,2} - &gt; 11

重申:如果通过包括原始集合的一些或所有元素而形成子集。因此,要创建子集,您将转到每个元素,然后决定是保留还是删除它。这意味着对于每个元素,您有2个决定。因此,对于一个集合,您最终可能会得到与2^N个不同子集相对应的2^N个不同的决策。

看看你是否可以从这里拿起它。

答案 1 :(得分:9)

功率集只是给定集的所有子集的集合。它包括所有子集(空集)。众所周知,这个集合中有2个 N 元素,其中N是原始集合中元素的数量。

要构建电源设置,可以使用以下内容:

  • 创建一个循环,迭代所有整数从0到2 N -1
  • 继续进行每个整数的二进制表示
  • 每个二进制表示都是一组N位(对于较小的数字,添加前导零)。如果特定集成员包含在当前子集中,则每个位对应。

示例,3个数字:abc

number binary  subset
0      000      {}
1      001      {c}
2      010      {b}
3      011      {b,c}
4      100      {a}
5      101      {a,c}
6      110      {a,b}
7      111      {a,b,c}

答案 2 :(得分:7)

  

创建一个权限集:{"A", "B", "C"}

<强>的伪代码:

val set = {"A", "B", "C"}

val sets = {}

for item in set:
  for set in sets:
    sets.add(set + item)
  sets.add({item})
sets.add({})

算法说明:

1)将sets初始化为空集:{}

2)对{"A", "B", "C"}

中的每个项目进行迭代

3)迭代set中的每个sets

3.1)创建一个新集合,它是set

的副本

3.2)将item附加到new set

3.3)将new set附加到sets

4)将item添加到sets

4)迭代完成。将空集添加到resultSets

<强>操作实例:

让我们在每次迭代后查看sets的内容:

迭代1,项目=&#34; A&#34;:

sets = {{"A"}}

迭代2,项目=&#34; B&#34;:

sets = {{"A"}, {"A", "B"}, {"B"}}

迭代3,项目=&#34; C&#34;:

sets = {{"A"}, {"A", "B"}, {"B"}, {"A", "C"}, {"A", "B", "C"}, {"B", "C"}, {"C"}}

迭代完成,添加空集:

sets = {{"A"}, {"A", "B"}, {"B"}, {"A", "C"}, {"A", "B", "C"}, {"B", "C"}, {"C"}, {}}

集合的大小为2 ^ | set | = 2 ^ 3 = 8这是正确的。

Java中的示例实现:

public static <T> List<List<T>> powerSet(List<T> input) {
  List<List<T>> sets = new ArrayList<>();
  for (T element : input) {
    for (ListIterator<List<T>> setsIterator = sets.listIterator(); setsIterator.hasNext(); ) {
      List<T> newSet = new ArrayList<>(setsIterator.next());
      newSet.add(element);
      setsIterator.add(newSet);
    }
    sets.add(new ArrayList<>(Arrays.asList(element)));
  }
  sets.add(new ArrayList<>());
  return sets;
}

输入:[A, B, C]

输出:[[A], [A, C], [A, B], [A, B, C], [B], [B, C], [C], []]

答案 3 :(得分:4)

好吧,你需要生成所有子集。对于一组大小为n,有 2 n 子集。

一种方法是迭代从0到2 n - 1的数字 并将每个转换为二进制数字列表,其中0表示排除 该元素和1表示包含它。

另一种方式是递归,分裂和征服。

答案 4 :(得分:3)

生成集合的所有组合(通过包含或不包含项目)。 通过例子解释: 一组(或列表)中的3个项目。可能的子集将是:

000   
100   
010   
001
110
101
011
111   

结果是2 ^(集合中的元素数量)。

因此我们可以生成N个项目的所有组合(使用python),如下所示:

def powerSet(items):

    N = len(items)

    for i in range(2**N):

        comb=[]
        for j in range(N):
            if (i >> j) % 2 == 1:
                comb.append(items[j])
        yield comb

for x in powerSet([1,2,3]):
    print (x)

答案 5 :(得分:0)

通过实施评分最高的答案,您会得到类似的结果。

def printPowerSet(set,set_size):

    # set_size of power set of a set
    # with set_size n is (2**n -1)
    pow_set_size = (int) (math.pow(2, set_size));
    counter = 0;
    j = 0;

    # Run from counter 000..0 to 111..1
    for counter in range(0, pow_set_size):
        for j in range(0, set_size):

            # Check if jth bit in the 
            # counter is set If set then 
            # pront jth element from set 
            if((counter & (1 << j)) > 0):
                print(set[j], end = "");
        print("");

答案 6 :(得分:0)

C#解决方案

时间复杂度和空间复杂度:O(n * 2 ^ n)

 public class Powerset
    {


        /*
         P[1,2,3] = [[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
             */
        public  List<List<int>> PowersetSoln(List<int> array)
        {

            /*
                We will start with an empty subset
                loop through the number in the array
                         loop through subset generated till and add the number to each subsets

              */

            var subsets = new List<List<int>>();
            subsets.Add(new List<int>());

            for (int i = 0; i < array.Count; i++)
            {
                int subsetLen = subsets.Count; 
                for (int innerSubset = 0; innerSubset < subsetLen; innerSubset++)
                {
                    var newSubset = new List<int>(subsets[innerSubset]);
                    newSubset.Add(array[i]);
                    subsets.Add(newSubset);
                }

            }

            return subsets;
        }
    }

答案 7 :(得分:-3)

示例Java代码:

void printPowerSetHelper(String s, String r) {
    if (s.length() > 0) {
        printPowerSetHelper(s.substring(1), r + s.charAt(0));
        printPowerSetHelper(s.substring(1), r);
    } 
    if (r.length() > 0) System.out.println(r);
}

void printPowerSet(String s) {
    printPowerSetHelper(s,"");
}