Obtaining a powerset of a set in Java

后端 未结 26 1697
青春惊慌失措
青春惊慌失措 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:46

    Here's a solution where I use a generator, the advantage being, the entire power set is never stored at once... So you can iterate over it one-by-one without needing it to be stored in memory. I'd like to think it's a better option... Note the complexity is the same, O(2^n), but the memory requirements are reduced (assuming the garbage collector behaves! ;) )

    /**
     *
     */
    package org.mechaevil.util.Algorithms;
    
    import java.util.BitSet;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.TreeSet;
    
    /**
     * @author st0le
     *
     */
    public class PowerSet implements Iterator>,Iterable>{
        private E[] arr = null;
        private BitSet bset = null;
    
        @SuppressWarnings("unchecked")
        public PowerSet(Set set)
        {
            arr = (E[])set.toArray();
            bset = new BitSet(arr.length + 1);
        }
    
        @Override
        public boolean hasNext() {
            return !bset.get(arr.length);
        }
    
        @Override
        public Set next() {
            Set returnSet = new TreeSet();
            for(int i = 0; i < arr.length; i++)
            {
                if(bset.get(i))
                    returnSet.add(arr[i]);
            }
            //increment bset
            for(int i = 0; i < bset.size(); i++)
            {
                if(!bset.get(i))
                {
                    bset.set(i);
                    break;
                }else
                    bset.clear(i);
            }
    
            return returnSet;
        }
    
        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not Supported!");
        }
    
        @Override
        public Iterator> iterator() {
            return this;
        }
    
    }
    

    To call it, use this pattern:

            Set set = new TreeSet ();
            for(int i = 0; i < 5; i++)
                set.add((char) (i + 'A'));
    
            PowerSet pset = new PowerSet(set);
            for(Set s:pset)
            {
                System.out.println(s);
            }
    

    It's from my Project Euler Library... :)

提交回复
热议问题