对于给定的n,生成集合{1,2……n - 1}的子集
简单枚举有三种办法
1,增量构造法
一次选出一个元素放到集合中,每一次递归都需要输出集合,因为是子集
#include<cstdio>
int A[1000000];void print_subset(int n, int cur){for(int i = 0; i < cur; i++) printf("%d ", A[i]);putchar('\n');for(int i = cur ? A[cur - 1] + 1 : 0; i < n; i++){A[cur] = i;print_subset(n, cur + 1);}
}int main(void)
{int n; scanf("%d", &n);print_subset(n, 0);return 0;
}
2,位向量法
对于每一个集合的位置,都用一个bool元素代表是否在集合中,因此是到n = cur的时候再输出集合
#include<cstdio>
bool B[1000000];void print_subset(int n, int cur){if(cur == n){for(int i = 0; i < n; i++)if(B[i]) printf("%d ", i);putchar('\n');}else{B[cur] = false;print_subset(n, cur + 1);B[cur] = true;print_subset(n, cur + 1);}
}int main(void)
{int n; scanf("%d", &n);print_subset(n, 0);return 0;
}
3,二进制法
和位向量法差不多,用一个标准表示这个元素是否存在,然后进行枚举,不过这里用的是二进制
#include<cstdio>void print_subset(int n, int s){for(int i = 0; i < n; i++)if(s & (1 << i)) printf("%d ", i);putchar('\n');
}int main(void)
{int n; scanf("%d", &n);for(int i = 0; i < (1 << n); i++)print_subset(n, i);return 0;
}