由于Java中有很方便的 String Integer.toBinaryString(int),在学习生成子集的时后看到用比特串生成幂集的算法,就想着用java实现一下。幂集在解背包问题的时候还是很有用的,蛮力法,简单粗暴有效,当然仅限较小的实例。
实现如下 PowerSetGenerator.java,其中容器的实现用LinkedHashSet是为了保证集合中元素的位置固定,方便测试:
package powerset;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Iterator;
public class PowerSetGenerator {
public Collection> getPowerSet(Collection set){
Collection> r = new LinkedHashSet>();
int binary = 1<
for(int i=0;i
r.add(getSubSet(set,i));
}
return r;
}
private Collection getSubSet(Collection set,int binarySeq){
Collection sub = new LinkedHashSet();
int mask = 1 <
Iterator it = set.iterator();
while(it.hasNext()){
T obj = it.next();
mask >>>= 1;
if((binarySeq & mask)!=0){
sub.add(obj);
}
}
return sub;
}
}
groovy单元测试 PowerSetTest.groovy,相当方便,特别是构建集合:
package powerset;
import static org.junit.Assert.*;
import org.junit.Test;
class PowerSetTest {
static def set = ['a','b','c']
static def result = [[], ['c'], ['b'], ['b', 'c'], ['a'], ['a', 'c'], ['a', 'b'], ['a', 'b', 'c']]
static def set2 = [1,2,3,4]
static def result2 = [[], [4], [3], [3, 4], [2], [2, 4], [2, 3], [2, 3, 4], [1], [1, 4], [1, 3], [1, 3, 4], [1, 2], [1, 2, 4], [1, 2, 3], [1, 2, 3, 4]]
static def set3 = [1]
static def result3 = [[], [1]]
@Test
public void test() {
PowerSetGenerator generator = new PowerSetGenerator();
assertEquals(result.toString(),generator.getPowerSet(set).toString());
assertEquals(result2.toString(),generator.getPowerSet(set2).toString());
assertEquals(result3.toString(),generator.getPowerSet(set3).toString());
}
}