问题描述:列出给定集合的所有子集合,包括空子集。
思路:一个集合的所有子集合的个数是个(n是集合中元素的个数),而一个位数为n的二进制也可以表示个数,所以,只要产生出了所有二进制数,就可以列出所有的子集了。在二进制的求解中,先来看这样一个例子。
11111 01111
+ 1
--------------------
11111 10000
当这个数加1时,如果当前位是1,那么当前位就变成0并且向前进1位;接着前一位如果是1,也会变成0并且继续进位;以此类推,直到遇到当前位是0的情况,就变成1,然后整个加法就完成了。依照此思路,很容易写出代码。
1 #include <stdio.h> 2 #include <math.h> 3 #define MAX 1000 4 5 int n=4;// the number of the set elements 6 int set[MAX]={1,2,3,4}; 7 int path[MAX]={0}; 8 int count=1; 9 10 //prototype 11 void print_set(); 12 13 int main() 14 { 15 int sum=(int)pow(2.0,n)-1; 16 int index,index_re; 17 printf("%d:{}\n",count); 18 for(index=0;index<sum;index++) 19 { 20 for(index_re=n-1;index_re>=0;index_re--) 21 { 22 if(path[index_re]==1) 23 path[index_re]=0; 24 else 25 { 26 path[index_re]=1; 27 break; 28 } 29 } 30 count++; 31 printf("%d:{",count); 32 print_set(); 33 } 34 return 0; 35 } 36 37 void print_set() 38 { 39 int index; 40 for(index=0;index<n;index++) 41 { 42 if(path[index]!=0) 43 printf("%d ",set[index]); 44 } 45 printf("}\n"); 46 }
参考资料:《C语言名题精选百则技巧篇》