Obtaining a powerset of a set in Java

后端 未结 26 1699
青春惊慌失措
青春惊慌失措 2020-11-22 11:33

The powerset of {1, 2, 3} is:

{{}, {2}, {3}, {2, 3}, {1, 2}, {1, 3}, {1, 2, 3}, {1}}

Let\'s say I have a Set in Java:<

26条回答
  •  粉色の甜心
    2020-11-22 11:51

    I came up with another solution based on @Harry He's ideas. Probably not the most elegant but here it goes as I understand it:

    Let's take the classical simple example PowerSet of S P(S) = {{1},{2},{3}}. We know the formula to get the number of subsets is 2^n (7 + empty set). For this example 2^3 = 8 subsets.

    In order to find each subset we need to convert 0-7 decimal to binary representation shown in the conversion table below:

    ConversionTable

    If we traverse the table row by row, each row will result in a subset and the values of each subset will come from the enabled bits.

    Each column in the Bin Value section corresponds to the index position in the original input Set.

    Here my code:

    public class PowerSet {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        PowerSet ps = new PowerSet();
        Set set = new HashSet();
        set.add(1);
        set.add(2);
        set.add(3);
        for (Set s : ps.powerSet(set)) {
            System.out.println(s);
        }
    }
    
    public Set> powerSet(Set originalSet) {
        // Original set size e.g. 3
        int size = originalSet.size();
        // Number of subsets 2^n, e.g 2^3 = 8
        int numberOfSubSets = (int) Math.pow(2, size);
        Set> sets = new HashSet>();
        ArrayList originalList = new ArrayList(originalSet);
        for (int i = 0; i < numberOfSubSets; i++) {
            // Get binary representation of this index e.g. 010 = 2 for n = 3
            String bin = getPaddedBinString(i, size);
            //Get sub-set
            Set set = getSet(bin, originalList));
            sets.add(set);
        }
        return sets;
    }
    
    //Gets a sub-set based on the binary representation. E.g. for 010 where n = 3 it will bring a new Set with value 2
    private Set getSet(String bin, List origValues){
        Set result = new HashSet();
        for(int i = bin.length()-1; i >= 0; i--){
            //Only get sub-sets where bool flag is on
            if(bin.charAt(i) == '1'){
                int val = origValues.get(i);
                result.add(val);
            }
        }
        return result;
    }
    
    //Converts an int to Bin and adds left padding to zero's based on size
    private String getPaddedBinString(int i, int size) {
        String bin = Integer.toBinaryString(i);
        bin = String.format("%0" + size + "d", Integer.parseInt(bin));
        return bin;
    }
    
    }
    

提交回复
热议问题