您的位置:首页 > 其它

求一个集合所有可能的子集

2016-10-08 20:02 288 查看
【1】增量构造法

一次选出一个元素放到集合中

<pre name="code" class="cpp">#include<iostream>
#include<vector>
using namespace std;
const int MAX = 100;
int layer = -1; //递归层数
int count1 = 0;
void print_subset(int n, int *A, vector<int> &vi, int cur)
{
cout << "layer:" << (++layer)<<endl;
count1++;
for (int i = 0; i < cur; i++)
{
cout << vi[A[i]] << " ";
}
cout << endl;

int s = cur ? A[cur - 1] + 1 : 0;//使用定序的技巧,规定集合A中所有元素的编号从小到大排列,就不会将{1,2}按照{1,2}与{2,1}输出两次了
for (int i = s; i < n; i++)
{
A[cur] = i;
print_subset(n, A, vi, cur + 1);
}
layer--;
}

int main()
{
int n,m,B[MAX];
scanf("%d", &n);
vector<int> vec;
for (int i = 0; i < n; i++)
{
cin >> m;
vec.push_back(m);
}
print_subset(n, B, vec, 0);
cout << "number of set:" << count1 << endl;
return 0;
}


【位向量法】

构造一个位向量B[i],其中当B[i]==1的时候i元素在子集a[]中,B[i]==0时不在子集a[]中。

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;

const int MAX = 100;
int count1 = 0;
int layer = -1;
void fullCombination(vector<int> &vi,int n, int* B, int cur)
{
cout<<"layer:"<<(++layer)<<endl;
if (cur == n)
{
count1++;
for (int i = 0; i < cur; i++)
{
if (B[i])
cout << vi[i] << " "; // 打印当前集合
}
printf("\n");
layer--;
return;
}
B[cur] = 1; // 选第cur个元素
fullCombination(vi,n, B, cur + 1);
B[cur] = 0; // 不选第cur个元素
fullCombination(vi, n, B, cur + 1);
layer--;
}

int main()
{
int B[MAX], n,m;
vector<int>vec;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> m;
vec.push_back(m);
}
fullCombination(vec,n, B, 0);
cout << count1 << endl;
return 0;
}


【3】二进制法

#include<cstdio>
#include<iostream>
#include<vector>
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);
printf("\n");
}

int main()
{
int n;
cin >> n;

for (int i = 0; i < (1 << n); i++)
print_subset(n, i);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: