001 /*
002 * $Id: PowerSet.java 3571 2011-03-18 22:02:51Z kredel $
003 */
004
005 package edu.jas.util;
006
007
008 import java.util.Iterator;
009 import java.util.LinkedList;
010 import java.util.List;
011
012
013 /**
014 * Power set with iterator.
015 * @author Heinz Kredel
016 */
017 public class PowerSet<E> implements Iterable<List<E>> {
018
019
020 /**
021 * data structure.
022 */
023 public final List<E> set; // Iterable<E> also ok
024
025
026 /**
027 * PowerSet constructor.
028 * @param set generating set.
029 */
030 public PowerSet(List<E> set) {
031 this.set = set;
032 }
033
034
035 /**
036 * get an iterator over subsets.
037 * @return an iterator.
038 */
039 public Iterator<List<E>> iterator() {
040 return new PowerSetIterator<E>(set);
041 }
042
043 }
044
045
046 /**
047 * Power set iterator.
048 * @author Heinz Kredel
049 */
050 class PowerSetIterator<E> implements Iterator<List<E>> {
051
052
053 /**
054 * data structure.
055 */
056 public final List<E> set;
057
058
059 final List<E> rest;
060
061
062 final E current;
063
064
065 private PowerSetIterator<E> recIter;
066
067
068 enum Mode {
069 copy, extend, first, done
070 };
071
072
073 Mode mode;
074
075
076 /**
077 * PowerSetIterator constructor.
078 * @param set generating set.
079 */
080 public PowerSetIterator(List<E> set) {
081 this.set = set;
082 if (set == null || set.size() == 0) {
083 current = null;
084 recIter = null;
085 rest = null;
086 mode = Mode.first;
087 return;
088 }
089 mode = Mode.copy;
090 current = set.get(0);
091 rest = new LinkedList<E>(set);
092 rest.remove(0);
093 recIter = new PowerSetIterator<E>(rest);
094 }
095
096
097 /**
098 * Test for availability of a next subset.
099 * @return true if the iteration has more subsets, else false.
100 */
101 public boolean hasNext() {
102 if (mode == Mode.first) {
103 return true;
104 }
105 if (recIter == null) {
106 return false;
107 }
108 return recIter.hasNext() || mode == Mode.copy;
109 }
110
111
112 /**
113 * Get next subset.
114 * @return next subset.
115 */
116 public List<E> next() {
117 if (mode == Mode.first) {
118 mode = Mode.done;
119 List<E> first = new LinkedList<E>();
120 return first;
121 }
122 if (mode == Mode.extend) {
123 if (recIter.hasNext()) {
124 List<E> next = new LinkedList<E>(recIter.next());
125 next.add(current);
126 return next;
127 }
128 }
129 if (mode == Mode.copy) {
130 if (recIter.hasNext()) {
131 return recIter.next();
132 }
133 mode = Mode.extend;
134 recIter = new PowerSetIterator<E>(rest);
135 return this.next();
136 }
137 return null;
138 }
139
140
141 /**
142 * Remove the last subset returned from underlying set if allowed.
143 */
144 public void remove() {
145 throw new UnsupportedOperationException("cannnot remove subsets");
146 }
147
148 }