Как генерировать набор мощности данного набора?

Я учусь на интервью, и я наткнулся на этот вопрос в интернете в категории "математика".

генерировать набор мощности заданного набора:

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;

 }

пожалуйста, я не хочу прямого ответа. Я просто хочу разъяснения и подсказки о том, как подойти к этой проблеме.

Я проверил алгоритм набора мощности в google, и я до сих пор не понимаю, как решить эту проблему.

кроме того, может ли кто-нибудь повторить, что задает вопрос для.

спасибо.

7 ответов


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

не самое дружелюбное определение в мире, но пример поможет :

например. для {1, 2}, подмножества:{}, {1}, {2}, {1, 2}

таким образом, набор мощности {{}, {1}, {2}, {1, 2}}


Чтобы создать набор мощности, обратите внимание, как вы создаете подмножество : вы переходите к каждому элементу по одному, а затем либо сохраняете его, либо игнорируете.

пусть это решение будет обозначено бит (1/0).

таким образом, чтобы создать {1}, вы будете забрать 1 и падение 2 (10).

на подобных строках вы можете написать битовый вектор для всех подмножеств:

  • {} -> 00
    {1} -> 10
    {2} -> 01
    {1,2} -> 11

повторить: подмножество, если оно сформировано путем включения некоторых или всех элементов исходного набора. Таким образом, чтобы создать подмножество, вы переходите к каждому элементу, а затем решаете, сохранить его или удалить. Это означает, что для каждого элемент, у вас есть 2 решения. Таким образом, для набора вы можете получить 2^N различные решения, соответствующие 2^N различные подмножества.

посмотрите, можете ли вы забрать его отсюда.


Power set - это просто набор всех подмножеств для данного набора. Он включает в себя все подмножества (с пустым набором). Хорошо известно, что есть 2N элементы в этом наборе, где N - количество элементов в исходном наборе.

для построения набора мощности можно использовать следующую вещь:

  • создайте цикл, который повторяет все целые числа от 0 до 2N-1
  • перейти к двоичному представлению для каждого целого числа
  • каждого двоичного представление представляет собой набор N bits (для меньших чисел добавьте ведущие нули). Каждый бит соответствует, если определенный элемент набора включен в текущее подмножество.

Пример, 3 числа:a, b, c

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}

создать набор питания:{"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 to sets.

4) Добавить item на sets.

4) итерация завершена. Добавьте пустой набор в свой resultSets.


пример:

давайте посмотрим на содержание sets после каждой итерации:

итерация 1, item = "A":

sets = {{"A"}}

итерация 2, item = "Б":

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

итерация 3, пункт = "C":

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], []]


Ну, вам нужно создать все подмножества. Для набора размера n, есть 2n подмножеств.

одним из способов было бы перебирать числа от 0 до 2n - 1 и преобразовать каждый в список двоичных цифр, где 0 значит исключить этот элемент и 1 значит включить его.

другой способ был бы с рекурсией, разделением и завоеванием.


создание всей комбинации набора (путем включения или не включения элемента). объясните на примере: 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)

вы получаете что-то вроде этого, реализуя лучший ответ.

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("");

Пример Кода 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,"");
}