求一个集合所有可能的子集
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;
}
一次选出一个元素放到集合中
<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;
}
相关文章推荐
- 给定一个可能包含重复的整数的集合,S返回所有可能的子集。
- 列出一个集合的所有非空子集
- 产生一个集合的所有子集
- 两种方法寻找一个集合的所有子集
- 一个集合的所有子集的Java代码实现
- 输出一个集合的所有子集(算法)
- 获取一个集合的所有子集
- 求一个集合的所有子集问题
- 求一个集合的所有子集
- 输出一个集合的所有子集(算法)
- 一个集合所有子集和为sum的组合打印
- 求一个集合的所有子集
- 生成一个整数集合的所有子集
- 输出一个集合的所有子集,从长到短
- 算法作业:求一个集合中所有子集元素之和
- 求一个集合的所有子集
- 给定一个集合(字符数组),打印出它的所有子集
- 生成一个集合的所有子集 Subset
- 求一个集合的所有子集问题
- 输出一个集合的所有子集(算法)