您的位置:首页 > 其它

7.3子集生成

2017-02-08 18:06 113 查看
给定一个集合,枚举所有可能的子集,本节讨论的集合中没有重复元素

7.3.1 增量构造法

第一种思路一次选出一个元素放到集合中

#include<stdio.h>
#include<cstring>
using namespace std;
int A[100];
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;
for(int i=s;i<n;i++){
A[cur]=i;
print_subset(n,A,cur+1);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(A,0,sizeof A);
print_subset(n,A,0);
}
return 0;
}


上面的代码用到了定序的技巧:规定集合A中所有元素的编号从小到大排列
7.3.2 位向量法

构造一个位向量B[i],而不是直接构造子集A本身,其中B[i]=1,当且仅当i在子集A中

#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int* B,int cur){
if(cur==n){
for(int i=0;i<cur;i++)
if(B[i])
printf("%d ",i);
printf("\n");
return;
}
B[cur]=1; //选第cur个元素
print_subset(n,B,cur+1);
B[cur]=0;
print_subset(n,B,cur+1);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(B,0,sizeof B);
print_subset(n,B,0);
}
return 0;
}


7.3.3 二进制法
为了处理方便,最右边的位总是对应元素0,而不是元素1

#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
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;
while(~scanf("%d",&n))
{
for(int i=0;i<(1<<n);i++)
print_subset(n,i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: