排列组合-生成集合的所有子集
//一个有N个不重复元素的集合的某个子集,可以用这个N个元素中每个元素在或是不在这个子集中来表示。
//把这N个元素一字排开,每个位置可以用1来标识对应位置的元素在子集中,用0来标识这个元素不在子集中
//依据计数的乘法原理这样的排列数有2^N个,也就是一个有N个不重复元素的集合有2^N个子集。
//而这种10表示方式刚好与N元的二进制串一一对应。
public class CombinationAll
{
public static void main(String[] args)
{
//指定集合的元素个数N
int N=Integer.parseInt(args[0]);
//使用一个长度为N的一维数组来表示N元的2进制串
int[] bin=new int[N];
//并从00...000开始,到11..111结束。
//由于检查11...111会花费较多的比较,改用计数器来实现。
for(int i=0;i<N;i++)
bin[i]=0;
show(bin);
//计数器标识还剩多少个子集没有列出
double Total=Math.pow(2,N)-1;
//二进制串每次增加1,计数器每次减1
int i;
while(Total>0)
{
//从低位向高位找到第一个0,然后将这个0变成1,将这个位置后面的1全变成0
for(i=N-1;i>=0 && bin[i]==1;i--)
bin[i]=0;
bin[i]=1;
show(bin);
Total--;
}
}
//显示这个数组中的二进制串
private static void show(int[] bin)
{
for(int i=0;i<bin.length;i++)
StdOut.printf("%d",bin[i]);
StdOut.println();
}
}