子集生成(二进制法,逐步生成,递归增量)

子集生成的三种方法

二进制法

1.不算空集,共有2^n-1个子集
2.对应二进制数的第N为1,则将A[N]选中,否则不选
子集生成(二进制法,逐步生成,递归增量)_第1张图片

逐步生成法

对每一个元素进行处理,每一个元素都可以被选中或者不选中

递归增量构造法

和逐步生成方法无异,只是采用递归的方法

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class 非空子集 {
    public static void main(String[] args) {
        int []a=new int[]{1,2,4};
//        递归增量构造法
        Set<Set<Integer>> res=getSubCore3(a,a.length);
        System.out.println(res.size());
        System.out.println(res);
//        迭代法
        a=new int[]{15,48,32,21};
        res=getSubCore2(a,a.length);
        System.out.println(res.size());
        System.out.println(res);
        //二进制法
        a=new int[]{1,2,4};
        res=getSubCore1(a,a.length);
        System.out.println(res.size());
        System.out.println(res);
    }
//    递归增量
    static Set<Set<Integer>> getSubCore3(int []A,int n){
        Arrays.sort(A);//按字典序
        return getSet3(A,A.length,n-1);
    }
//    递归增量构造
//    添加元素 不添加元素(保留原样
    private static Set<Set<Integer>> getSet3(int[] a, int n, int cur) {;
        Set<Set<Integer>> newSet=new HashSet<>();
        if(cur==0){
            Set<Integer> nil=new HashSet<>();
            Set<Integer> frist=new HashSet<>();
            frist.add(a[0]);//保留原样
            newSet.add(nil);
            newSet.add(frist);
            return newSet;
        }
//        调用下一个元素
        Set<Set<Integer>> oldSet=getSet3(a,n,cur-1);
        for (Set<Integer> set:oldSet) {
            newSet.add(set);
            Set<Integer> clone=(Set<Integer>)((HashSet)set).clone();
            clone.add(a[cur]);
            newSet.add(clone);
        }
        return newSet;
    }

//    逐步迭代生成法
    static Set<Set<Integer>> getSubCore2(int []a ,int n){
        Arrays.sort(a);//按字典序
        Set<Set<Integer>> res =new HashSet<>();//新建一个集合
        res.add(new HashSet<>());//添加空集合进去
        for(int i=0;i<n;i++){//从第一个元素开始处理
            Set<Set<Integer>>  res_new =new HashSet<>();//新建集合
            res_new.addAll(res);//添加进之前的集合
            for (Set<Integer> set:res//遍历之前那集合的每一个元素
            ){
                Set clone=(Set)((HashSet)(set)).clone();//克隆
                clone.add(a[i]);//添加当前数组元素
                res_new.add(clone);//添加进集合

            }
            res=res_new;//更新原有的集合
        }
        return res;//返回原来的集合
    }
//    二进制法 非空子集 若第n位为1,则将A[n]添加进去
    static Set<Set<Integer>> getSubCore1(int []a,int n){
        Arrays.sort(a);//按字典序
        Set<Set<Integer>> res=new HashSet<>();
        for(int i=(int)(Math.pow(2,n)-1);i>0;i--){
            Set<Integer> ans=new HashSet<>();
            for(int j=n-1;j>=0;j--){
                if(((i>>j)&1)==1){
                    ans.add(a[j]);
                }
            }
            res.add(ans);
        }
        return res;
    }
}

你可能感兴趣的:(子集生成(二进制法,逐步生成,递归增量))