子集生成
程序员文章站
2024-03-21 19:12:22
...
一、增量构造法产生没有重复元素集合的所有子集
#include<iostream>
#include<cstdio>
#include<algorithm>
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; //s用来确定当前开始的最小位置
for(int i = s; i < n; i++)
{
A[cur] = i;
print_subset(n, A, cur+1);
}
}
int main()
{
int A[100];
int n;
cin >> n;
for(int i = 0; i < n; i++)
cin >> A[i];
sort(A, A+n);
print_subset(n+1, A, 1);
return 0;
}
二、位向量法
#include<iostream>
#include<cstdio>
using namespace std;
void print_subset(int n, int* B, int cur)
{
if(cur == n)
{
for(int i = 1; i <= cur; i++)
if(B[i]) printf("%d ", i);
printf("\n");
return ;
}
B[cur] = 1;
print_subset(n, B, cur+1);
B[cur] = 0;
print_subset(n, B, cur+1);
}
int main()
{
int n;
cin >> n;
int A[10];
print_subset(n, A, 0);
return 0;
}
三、二进制法
#include<iostream>
#include<cstdio>
using namespace std;
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;
cin >> n;
for(int i = 1; i < (1<<n); i++)
print_subset(n, i);
return 0;
}
关于位运算的补充:
/*
关于位运算的学习:
A&B: 求的是集合A和集合B的交集
A|B: 求的是集合A和集合B的并集
A^B: 求的是集合A和集合B的对称差((A|B)- (A&B))
空集为0;
全集 : ALL_BITS = (1<<n) - 1;
补集 : ALL_BITS ^ A;
*/