1、增量构造法
注意:在枚举子集的增量法中,需要使用定序的技巧,避免同一个集合枚举两次,比如{1,2}和{2,1}。
实例:
2、位向量法
3、二进制法
与按位输出差不多
注意:在枚举子集的增量法中,需要使用定序的技巧,避免同一个集合枚举两次,比如{1,2}和{2,1}。
实例:
#include <iostream>
using namespace std;
void print_subset(int n, int * A, int cur){
for(int i = 0; i < cur; i++) //只要其中有数,就需要输出
cout<<A[i];
cout<<endl;
int s = cur ? A[cur - 1] + 1 : 0; //如果cur不等于零,将由已有序列中的最大的加一开始遍历
for(int i = s; i < n; i++){
A[cur] = i;
print_subset(n, A, cur + 1);
}
}
int main(){
int A[1000];
int n;
cin>>n;
for(int i = 0; i < n; i++){
cin>>A[i];
}
print_subset(n, A, 0);
return 0;
}
2、位向量法
#include <iostream>
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]) cout<<i;
}
cout<<endl;
return;
}
B[cur] = 1; //此位存在标1
print_subset(n, B, cur + 1);
B[cur] = 0; //此位不存在标0
print_subset(n, B, cur + 1);
}
int main(){
int n;
cin>>n;
int B[1000] = {0};
print_subset(n, B, 0);
return 0;
}
3、二进制法
与按位输出差不多
#include <stdio.h>
void print_subset(int n, int s){
for(int i = 0; i < n; i++){
if(s & (1<<i)) printf("%d", i);
}
printf("\n");
}
int main(){
int n;
scanf("%d", &n);
for(int i = 0; i < (1<<n); i++){
print_subset(n, i);
}
return 0;
}