[算法]暴力求解法:子集生成

增量构造法

每次选择一个元素放到集合A中,使用递归

import java.util.*;
import java.util.Arrays;

public class Main {
	public static void subset(int n,int[] a,int cur) {
		for(int i=0;i<cur;i++) {
			System.out.print(a[i]+" ");
		}
		System.out.println();
		int s=cur>0? a[cur-1]+1:0; //定序,避免同一个集合枚举两次
		for(int i=s;i<n;i++) {
			 a[cur] = i;
             subset(n,a,cur+1);
		}
		
	}
	
	public static void main(String[] args) {
		Scanner s=new Scanner(System.in);
		int n= s.nextInt();
		int[] a=new int[100];
		subset(n,a,0);
	}
}

位向量法

  1. 构造一个位向量B[i],而不是直接构造子集A本身,其中B[i]=1,当且仅当i在子集A中。
  2. 必须当“所有元素是否选择”全部确定完毕后才是一个完整的子集,因此仍然像以前那样
    当if(cur == n)成立时才输出。
    递归实现如下:
import java.util.*;

public class Main {
	public static void subset(int n,int[] b,int cur) {
		if(cur==n) {
			for(int i=0;i<cur;i++) {
				if(b[i]==1)
					System.out.print(i+" ");
			}
			System.out.println();
			return;
		}
		b[cur]=1;
		subset(n,b,cur+1);//选第cur个元素 
	    b[cur]=0;
	    subset(n,b,cur+1);//不选第cur个元素 
	}
	
	public static void main(String[] args) {
		Scanner s=new Scanner(System.in);
		int n= s.nextInt();
		int[] b=new int[100];
		subset(n,b,0);
	}
}

二进制法

import java.util.*;

public class Main {
	public static void subset(int n,int s) {
		for(int i=0;i<n;i++)
	    {
	        if((s&(1<<i))!=0) 
	        	System.out.print(i); 
	    }
		System.out.println();
	}
	
	public static void main(String[] args) {
		Scanner s=new Scanner(System.in);
		int n= s.nextInt();
		int[] b=new int[100];
		int[] p=new int[20];
		for(int i=0;i<n;i++){
			//p[i]=s.nextInt();
		}
		//Arrays.sort(p,0,n);
		//permutation_p(n,p,a,0);
		for(int i=0;i<(1<<n);i++)
			subset(n,i);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41655934/article/details/89212612
今日推荐