求一个集合的子集

第一种方法就是先不断到加元素,然后再考虑删去一个元素,再加一个新到元素进来

 

1 void print_subset(int n,int A[],int cur) {
2     for (int i=0;i<cur;i++)
3         printf("%d ",A[i]);
4     printf("\n");
5     int s = cur ? A[cur-1]+1 : 0;
6     for (int i=s;i<n;i++) {
7         A[cur] = i;
8         print_subset(n,A,cur+1);
9     }

 

第二种方法就更好理解了,就是对于每个元素我们都有两种情况(取和不取)

 

 1 void print_Subset(int n,int B[],int cur) {
 2     if (cur == n) {
 3         for (int i=0;i<cur;i++) {
 4            if (B[i])
 5                printf("%d ",i);
 6         }
 7         printf("\n");
 8         return ;
 9     }
10     B[cur] = 1;
11     print_Subset(n,B,cur+1);
12     B[cur] = 0;
13     print_Subset(n,B,cur+1);
14 }

 

第三种方法 二进制!

二进制的方法很简单,其实就是把二进制的 0 和 1 当成一个 “开关”。1 代表选取,0 代表不选。

其实二进制的每一位其实对应的是我们所给数组的下标的映射(我个人理解是这样的)

 

求长度为 n 的并且是从0~n-1 的连续数组的子集

1 void print_subset(int n,int s) {
2     for (int i=0;i<n;i++) {
3         if (s & (1<<i))
4             printf("%d ",i);
5     }
6     printf("\n");
7 }

 

求长度为 n 的任意的数组的子集   如果理解了我前面说的二进制是对数组下标的一个映射,这个就很简单

1 int a[3] = {5, 4, 6};
2 
3 void print_subset(int n,int s) {
4     for (int i=0;i<n;i++) {
5         if (s & (1<<i))
6             printf("%d ",a[i]);
7     }
8     printf("\n");
9 }

 

 

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务