0
点赞
收藏
分享

微信扫一扫

紫书之子集生成三种算法

代码敲到深夜 2022-07-12 阅读 25


问题描述:

给定一个集合,比如{1,2,3,4},要生成所有的子集(不包括空集,也就是2^n-1个集合)

注: n个元素集合有2^n个子集.

1.增量构造法

思路:在已有子集的基础上不断增加新的元素,一直到无法继续添加为止. 另外因为我们排序的是数组的索引,是从小到大的,就不会出现重复的了.

参考代码

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

int A[101];//存放集合元素下标的的数组

void print_subset(int n,int *A,int cur){//cur:当前A序列中元素的个数.
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 一定包含A[s]元素, 第二轮则是一定包含A[s+1]元素 A序列中的元素一定都是从小到达的
A[cur] = i;
print_subset(n,A,cur+1);//继续构造子集.
}

}

int main()
{
int n;
scanf("%d",&n);
print_subset(n,A,0);
return 0;
}

运行结果:

紫书之子集生成三种算法_i++

2.位向量法

思路:使用一个数组来进行标记对应位置的元素是否存在,标记位置为0表示不存在,为1表示存在.

参考代码

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

int B[10];

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;//不选第cur个元素
print_subset(n,B,cur+1);

}

int main()
{
int n;
scanf("%d",&n);
print_subset(n,B,0);
return 0;
}

运行结果

紫书之子集生成三种算法_ios_02

3.二进制法

有点复杂,自己目前还有点迷糊.

#include<cstdio>
#include<iostream>
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;
scanf("%d",&n);
for(int i = 0; i < (1<<n);i++){//
print_subset(n,i);
}
return 0;
}


举报

相关推荐

0 条评论