/**
* 功能:返回某集合的所有子集。
*/
三种方法:
方法一:迭代
//迭代
/**
* 注意:每次加入集合后会改变原来的集合,无法继续从集合中取出元素。
* 必须通过一个中间参数moreSubsets来保存中间结果,最后加入allSubsets。
* @author Lynne
* @param set
* @param index
* @return
*/
public static ArrayList<ArrayList<Integer>> getSubsets2(ArrayList<Integer> set,int index){
ArrayList<ArrayList<Integer>> allSubsets=new ArrayList<ArrayList<Integer>>();
allSubsets.add(new ArrayList<Integer> ());//加入空集合
while(index<set.size()){
int item=set.get(index);
ArrayList<ArrayList<Integer>> moreSubsets=new ArrayList<ArrayList<Integer>>();
for(ArrayList<Integer> subsets:allSubsets){
ArrayList<Integer> newSubsets=new ArrayList<Integer>();
newSubsets.addAll(subsets);
newSubsets.add(item);
moreSubsets.add(newSubsets);
}
allSubsets.addAll(moreSubsets);
index++;
}
return allSubsets;
}
方法二:递归
//递归法
/**
* 思路:简单构造法
* 计算P(n-1),复制一份结果,然后在每个复制后的集合中加入an。
* @param set
* @param index
* @return
*/
public static ArrayList<ArrayList<Integer>> getSubsets(ArrayList<Integer> set,int index){
ArrayList<ArrayList<Integer>> allSubsets;
if(set.size()==index){//终止条件,加入空集合
allSubsets=new ArrayList<ArrayList<Integer>>();
allSubsets.add(new ArrayList<Integer>());//空集合
}else{
allSubsets=getSubsets(set, index+1);
int item=set.get(index);
ArrayList<ArrayList<Integer>> moreSubsets=new ArrayList<ArrayList<Integer>>();
for(ArrayList<Integer> subsets:allSubsets){
ArrayList<Integer> newSubsets=new ArrayList<Integer>();
newSubsets.addAll(subsets);
newSubsets.add(item);
moreSubsets.add(newSubsets);
}
allSubsets.addAll(moreSubsets);
}
return allSubsets;
}
方法三:组合数学
//组合数学
/**
* 思路:迭代访问1到2^n的所有数字,再转化为集合
* 每个元素有两个选择:1)在集合中(“yes”);2)不在集合中(“no”)。即每个子集都是一串yes和no。
* 总共有2^n个子集,将每个yes看做1,每个no看做0,即可以表示为一个二进制串。
* 所以,构造所有的子集就等同于构造所有的二进制数。迭代访问1到2^n的所有数字,再转化为集合。
* @param set
* @return
*/
public static ArrayList<ArrayList<Integer>> getSubsets(ArrayList<Integer> set){
ArrayList<ArrayList<Integer>> allSubsets=new ArrayList<ArrayList<Integer>>();
int size=1<<set.size();//集合的子集个数,计算2^n。
for(int i=0;i<size;i++){
ArrayList<Integer> subsets=new ArrayList<Integer>();
subsets=convertIntToSet(i);
allSubsets.add(subsets);
}
return allSubsets;
}
public static ArrayList<Integer> convertIntToSet(int x){
ArrayList<Integer> subsets=new ArrayList<Integer>();
for(int i=x;i>=1;i>>=1){
if((i&1)==1)
subsets.add(i);
}
return subsets;
}