/**
* 功能:返回某集合的所有子集。
*/
三种方法:
方法一:迭代
[java]
- //迭代
- /**
- * 注意:每次加入集合后会改变原来的集合,无法继续从集合中取出元素。
- * 必须通过一个中间参数moreSubsets来保存中间结果,最后加入allSubsets。
- * Lynne
- * set
- * index
- *
- */
- 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;
- }
方法二:递归
[java]
- //递归法
- /**
- * 思路:简单构造法
- * 计算P(n-1),复制一份结果,然后在每个复制后的集合中加入an。
- * 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;
- }
方法三:组合数学
[java]
- //组合数学
- /**
- * 思路:迭代访问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;
- }