Нахождение набора мощности общего набора

Мне был задан вопрос об использовании дженериков Java и создании класса Set. Я смог выполнить другие функции, такие как объединение, пересечение, дополнение и т. д., используя этот класс Set.

Но проблема, с которой я столкнулся, заключается в том, чтобы найти все наборы мощности. Я должен вернуть набор (т.е. набор мощности). Я пытался решить эту проблему со вчерашнего дня, но безрезультатно. Я попытался реализовать бинарный метод, чтобы найти наборы мощности. Все, что я сделал до сих пор, основано на требованиях вопроса!

public class Set<T extends Comparable> {

private ArrayList<T> theSet;

public Set(T[] theElements){
    theSet = new ArrayList<>();
    for(int i=0; i < theElements.length; i++){
        if(!checker(theElements[i]))
            theSet.add(theElements[i]);
    }
}

public ArrayList<T> getTheSet() {
    return theSet;
}

public Set powerSet(){
    long powerSetSize = (long)Math.pow(2, theSet.size());
    int counter, j;
    Set[] powerSet = new Set[(int)Math.pow(2, theSet.size())];
    T[] currentArray = null;

    for(counter=0; counter<powerSetSize; counter++){
        for(j=0; j<theSet.size(); j++){
            currentArray = (T[]) new Comparable[j+1];
            if((counter & (1 << j)) > 0)
                currentArray[j] = theSet.get(j);
        }
        powerSet[counter] = new Set<>(currentArray);
    }

    return new Set<>((T[])powerSet);
}

public String toString(){
    String str = "{";
    for(int i=0; i<theSet.size(); i++){
        if(i < theSet.size()-1)
            str += theSet.get(i)+", ";
        else
            str += theSet.get(i)+"}";
    }
    return str;
}

}

person ft1    schedule 15.03.2020    source источник
comment
Я думаю, что рекурсия - ваш друг здесь. Проверьте это: baeldung.com/java-power-set-of- набор   -  person Stefan    schedule 15.03.2020


Ответы (1)


Вы можете попробовать следующее:

Сначала создайте массив целых чисел с длиной вашего базового набора, установив каждое целое число равным нулю. Имейте в виду, что каждый элемент нумеруется в соответствии с его положением в вашем базовом наборе +1, потому что вам нужен пустой элемент, который тогда равен нулю. Затем, конечно, сначала создайте набор наборов, который вы собираетесь вернуть в качестве набора мощности. После этого прокрутите свой массив целых чисел следующим образом: создайте набор из текущего целочисленного массива, проанализировав каждое целое число до соответствующего элемента набора. Затем добавьте единицу к первому целому числу вашего целочисленного массива. Если число больше, чем длина вашего базового набора, добавьте единицу к следующему целому числу вашего массива, установив «переполняющее» целое число равным следующему целому числу в массиве +1.

Это должно позволить вам просмотреть все возможные комбинации для набора мощности и добавить их в набор.

public Set<Set<T>> powerSet(){
    int[] num = new int[list.size()];
    Arrays.fill(num,0);
    Set<Set<T>> powerSet = new Set<>();
    do{
        powerSet.list.add(parse(num));
    }while (addNum(num)); //Loops through every possibility 
    powerSet.list.add(parse(num)); 
    //Because the method returns false when this was the last possible increment
    return powerSet;
}

//Transforms a int[] into the corresponding Set
private Set<T> parse(int[] e){
    Set<T> s = new Set<>();
    for (int i = 0; i < e.length; i++) {
        if(e[i]!=0){
            s.list.add(list.get(e[i]-1)); //Every Element has its number
        }
    }
    return s;
}

//Increments the counter
//Returns false if this was the last possible increment
private boolean addNum(int[] e){
    e[0]++;
    for (int i = 0; i < e.length; i++) {
        if(e[i]>e.length-i){
            e[i] = 0;
            e[i+1]++;
        }
    }
    for (int i = e.length-1; i != 0; i--) {
        if(e[i]>=e[i-1]&&e[i]!=0){
            e[i-1] = e[i]+1;
        }
    }
    if(e[e.length-1]==1){
        return false;
    }
    return true;
}

Вывод для [3,43,65,32] (распечатывается каждый набор набора мощности):

[]
[3]
[43]
[65]
[32]
[43, 3]
[65, 3]
[32, 3]
[65, 43]
[32, 43]
[32, 65]
[65, 43, 3]
[32, 43, 3]
[32, 65, 3]
[32, 65, 43]
[32, 65, 43, 3]

Хотя это может быть не самый элегантный способ решения проблемы, похоже, он работает. Я также не знаю требований вопроса. Так что, возможно, этот ответ даже не подходит.

person TheThingAboveMe    schedule 15.03.2020
comment
Мне нужен массив в качестве аргумента для инициализации моего набора. Это было включено в мой конструктор. - person ft1; 15.03.2020
comment
в основном это был вопрос и его критерии: prnt.sc/rgnuos & prnt.sc/rgnv79 - person ft1; 15.03.2020
comment
Затем вы можете немного изменить код, чтобы создать список, а затем получить из него массив с помощью toArray, который затем позволит вам создать свой набор. - person TheThingAboveMe; 15.03.2020
comment
Исключение в потоке main java.lang.ClassCastException: class [Lvivaset.Set; нельзя привести к классу [Ljava.lang.Comparable; ([Lvivaset.Set; находится в безымянном модуле загрузчика 'app'; [Ljava.lang.Comparable; находится в модуле java.base загрузчика 'bootstrap') - person ft1; 15.03.2020
comment
это ошибка, которую я получаю, когда пытаюсь вернуть свой набор мощности - person ft1; 15.03.2020