子集生成问题
来源:互联网 发布:ios 软件 目录 编辑:程序博客网 时间:2024/06/05 21:04
给你一个可比较大小顺序的集合,让你生成所有按照字典序排列的子集,本文借鉴自刘汝佳算法入门经典。
方法一:
增量构造法:一次选取一个元素到集合中。
#include <iostream>using namespace std;int a[20];/*递归输出n以内所有的子集,其中cur为当前下标,初始值0*/void print_subset(int n,int* a,int cur){for (int i=0;i<cur;i++)//每次递归输出当前子集,靠它来最后输出上一层指定的子集cout<<a[i]<<' ';cout<<endl;//找到当前子集首个值,因为按字典顺序输出,所以每次找到最小的元素,cur>0则minElem=a[cur-1]+1,否则为0int minElem = cur?a[cur-1]+1:0;for (i=minElem;i<n;i++)//设置每一层数的第一个值{a[cur]=i;//到达最后一层结束后自动回到上一层,然后i++,a[cur]的值(首元素)改变,又反复递归下一层...就像DFS树一样print_subset(n,a,cur+1);}}int main(){int n ;while (cin>>n){print_subset(n,a,0);}return 0;}
注意:在枚举子集的增量法中已经进行定序,避免了同一集合出现两次。例如:0 1被列为0 1和1 0
方法二:位向量法:通过构建位向量B[i],而不是直接构造子集A本身,当且仅当i在子集A中时,B[i]=1;
#include <iostream>using namespace std;bool b[20]={0};//判断当前每一个节点选中状态/*递归输出n以内所有的子集,其中b表示该节点是否选中,cur为当前下标,初始值0*/void print_subset(int n,bool* b,int cur){//当cur加到n的时候输出该串节点(解答树)的值if(cur==n){for (int i=0;i<n;i++){if(b[i])cout<<i<<' ';}cout<<endl;return ;}b[cur]=true;//该节点设为选中状态print_subset(n,b,cur+1);//cur+1递归该状态时的下一层节点,循环该操作b[cur]=false;//该节点设为不选中状态print_subset(n,b,cur+1);//cur+1递归该状态时的下一层节点,循环该操作}int main(){int n ;while (cin>>n,n){print_subset(n,b,0);}return 0;}
0 0
- 子集生成问题
- 子集生成问题-一道笔试题目
- uva11205 -(简单题) 生成子集问题
- 算法学习之子集生成问题
- 生成子集
- 子集生成
- 子集生成
- 子集生成
- 子集生成
- 子集生成
- 子集生成
- 生成子集
- 生成子集
- 子集生成
- 子集生成
- 子集生成
- 子集生成
- 子集生成
- 第八周项目三—switch 语句构造多分支结构
- Java集合类总结
- 研读java编程思想第二章--一切都是对象(everything is a object)(1)
- JAVA学习之 异常处理机制
- eclipse插件安装、卸载及其一个常见的安装问题
- 子集生成问题
- filechannel拷贝大文件
- 自动化测试selenium-java FireFox运行版本不兼容
- 加载ETC1格式编码的PVR压缩文件
- Matlab 批量建文件夹
- 1.4 平分两个正方形
- hdu 4956
- POJ 3250 Bad Hair Day 单调栈
- hdu 4946 凸包注意重点