【问题描述】
对于给定的正整数n(n>=1),求1~n构成的所有子集的集合(幂集)
解法1:
直接采用蛮力法求解,将1~n的存放在数组a中,求解问题变为构造集合a的所有子集。设集合a[0…2]={1,2,3},其所有子集对应的二进制位及其十进制数如下。
对于含有n(n>=1)个元素的集合a,求幂集的过程如下:
for(i=0;i<2^n;i++)
{
将i转换为二进制数b;
输出b中为1的位对应的a元素构成的一个子集;
}
算法时间复杂度为O(n*2^n)
代码实现:
void inc(int b[ ],int n)
{
for(int i=0;i<n;i++) {
if(b[i])
b[i]=0;
else{
{
b[i]=1
break;
}
}
}
void Pset(int a[ ],int b[ ],int n){
int i,k;
int pw=(int)pow(2,n);
printf("1~%d的幂集:\n",n);
for(i=0;i<pw;i++){
printf("{");
for(k=0;k<n;k++)
if(b[k])
printf("%d ",a[k]);
printf("}");
inc (b,n)
}
解法2:
采用增量蛮力法求解1~n的幂集
思想就是穷举1~n的所有子集。先建立一个空子集,对于i(1<=i<=n),每次都是在前面已建立的子集上增加元素i而构成若干个子集,对应的过程如下:
void f(int n){
ps={{}};
for(int i=1;i<=n;i++)
在ps的每个元素中增加i而构成一个新子集;
}
在实现算法时,用一个vector容器来表示一个集合元素,用vector<vector>容器来存放幂集。
代码实现:
#include<stdio.h>
#include<vector>
using namespacestd;
vector<vector<int>> ps; //用于存放幂集
void Pset(int n){
vector<vector<int> > ps1; //子幂集
vector<vector<int> >::iterator it; //迭代器
vector<int> s; //添加空集元素
ps.push_back(s);
for(int i=1;i<=n;i++){
ps1=ps; //ps1存放上一步骤得到的幂集
for(it=ps1.begin();it!=ps1.end();++it)
(*it).push_back(i); //在ps1的每个集合元素末尾添加i
for(it=ps1.begin();it!=ps1.end();++it)
ps.push_back(*it); //将ps1的每个集合元素添加到ps中
}
}