包含空集
代码来自紫书
// {0~n-1}的所有子集:增量构造法
// Rujia Liu
#include<cstdio>
#pragma warning(disable:4996)
using namespace std;
void print_subset(int n, int* A, int cur) {
for (int i = 0; i < cur; i++) printf("%d ", A[i]); // 打印当前集合
printf("\n");
int s = cur ? A[cur - 1] + 1 : 0; // 确定当前元素的最小可能值
for (int i = s; i < n; i++) {
A[cur] = i;
print_subset(n, A, cur + 1); // 递归构造子集
}
}
int A[10];
int main() {
int n;
while(scanf("%d", &n))
print_subset(n, A, 0);
return 0;
}
// {0~n-1}的所有子集:位向量法
// Rujia Liu
#include<cstdio>
using namespace std;
void print_subset(int n, int* B, int cur) {
if(cur == n) {
for(int i = 0; i < cur; i++)
if(B[i]) printf("%d ", i); // 打印当前集合
printf("\n");
return;
}
B[cur] = 1; // 选第cur个元素
print_subset(n, B, cur+1);
B[cur] = 0; // 不选第cur个元素
print_subset(n, B, cur+1);
}
int B[10];
int main() {
int n;
scanf("%d", &n);
print_subset(5, B, 0);
return 0;
}
// {0~n-1}的所有子集:二进制法
// Rujia Liu
#include<cstdio>
using namespace std;
void print_subset(int n, int s) { // 打印{0, 1, 2, ..., n-1}的子集S
for(int i = 0; i < n; i++)
if(s&(1<<i)) printf("%d ", i); // 这里利用了C语言“非0值都为真”的规定
printf("\n");
}
int main() {
int n;
scanf("%d", &n);
for(int i = 0; i < (1<<n); i++) // 枚举各子集所对应的编码 0, 1, 2, ..., 2^n-1
print_subset(n, i);
return 0;
}