子集生成算法 之 位向量法和增量构造法
什么是子集生成?
#include<iostream>
#include<stdio.h>
using namespace std;
int n;
int k1[10];
bool pd[10];void vec_cl (int cur)
{if (cur != 0){for (int i=0;i<n;i++){if (pd[i] == true){cout<<k1[i];}}cout<<endl;}if (cur == n)//设置递归出口,证明此时已经到达数据边界,开始弹出系统栈return ;for (int i=0;i<n;i++){if (pd[i] == false){pd[i] = true;//进行标记,表明此时数据已经在一个未知名的子集中存放vec_cl (i+1);pd[i] = false;//进行标记,表明此时子集已经输出完毕,开始找新的子集,同时要进行一个恢复原数据状态的操作}}
}int main ()
{while (cin>>n){memset(k1,0,sizeof(k1));memset(pd,false,sizeof(false));for (int i=0;i<n;i++){cin>>k1[i];}vec_cl (0);}return 0;
}
- 相比于其他两种算法(增量构造法,二进制法),这种算法理解起来比较容易
- 相比于其他两种算法,此种算法效率不够,我们需要访问解答树中的所有的节点,不满足我们设定的特定条件的节点也被访问了,这点我归纳为这是暴力求解法的一种算法。
#include<iostream>
#include<stdio.h>
using namespace std;
int n;
int k1[10];//存放具体数据
int pos[10];//存放每次查找下一个元素的在集合k1中元素的具体位置void add_cl (int cur)//从一定程度上,我们可以这么理解cur参数:即cur是我们进行图的遍历的层数
{if(cur != 0){for (int i=0;i<cur; i++){cout<<k1[pos[i]];}cout<<endl;}int dingwei = cur ? pos[cur-1] + 1 : 0;//这句对于大多数人来说比较晦涩难懂,下面注释部分为这句的较为通俗的写法//上面一句就是这个算法的核心------->> 我们的集合pos其实存放的数据是满足我们设置的一定条件的集合k1中的元素的具体位置//我们通过一些条件控制到达了避过一部分已经找到的子集目的,有效的过滤了不满足条件的集合,增加了我们进行了递归操作的效率/*if (cur == 0){dingwei = 0;}else{dingwei = pos[cur-1] + 1;}*/for (int i=dingwei;i<n;i++){pos[cur] = i;add_cl(cur+1);//这个算法的一个好处:我们不用特别的判断递归条件,因为我们进行的数组的遍历,我们通过循环无形中进行了控制,//也就是说在此时这个for循环的工作空间内,进行了添加数据的操作,如果不满足这个for循环的条件,我们就可以这么认为:无法添加新的元素,自然也就不会有递归了}
}int main ()
{while (cin>>n){memset(k1,0,sizeof(k1));memset(pos,0,sizeof(pos));for (int i=0;i<n;i++){cin>>k1[i];}add_cl (0);}return 0;
}
优点:
- 有效的控制了递归的运行效率,我们不用访问解答树的每一个节点,能比较快的查找下一个元素所在的位置
- 在特定的要求下,我们能进行比较好的条件控制,下面我会举一个例子。
- 比较抽象,有一点回溯的思想,我们也可以抽象成图的思想(毕竟树结构也是图的一个分支),如果理解这个算法,对于回溯会有比较好的理解。
#include<iostream>
#include<stdio.h>
using namespace std;
int n;
int k1[10],pos[10];void cl (int cur)
{if (cur==2){for (int i=0;i < cur ;i++){cout<<k1[pos[i]];}cout<<endl;}int dingwei = 0;if (cur == 0){dingwei = 0;}else{dingwei = pos[cur-1] + 1;}for (int i=dingwei; i<n;i++){pos[cur] = i;cl(cur+1);}
}int main ()
{while (cin>>n){memset(k1,0,sizeof(k1));for (int i=0;i<n;i++){cin>>k1[i];}memset(pos,false,10);cout<<"查看初始化的数组k1"<<endl;for (int i=0;i<10;i++){cout<<k1[i];}cout<<endl;cl(0);}return 0;
}
关于子集生成算法的二进制法,由于本人愚笨,还没有更好的领悟,只好在下一次更新中写出来分享给大家。
子集生成算法 之 位向量法和增量构造法相关推荐
- 计算几何入门 1.3:凸包的构造——增量构造法
极点法和极边法的复杂度分别为O(n^4)和O(n^3),当点集S的规模稍大时就难以适用了.为了满足实际需要必须寻找更高效的算法来构造凸包. 一.减治 在引入新算法之前首先来回顾一下经典的算法思想:减治 ...
- 子集生成 增量构造法 位向量法 二进制法
增量构造法 参考 //此算法仅仅是输出下标,实际应用应输入另一个数组来进行存储数据 //这三种方式,为了理解这个花费了最长的时间,太纠结于细节了,刘汝佳写的不是特别清楚 //这三种方式的话,都可以理解 ...
- 浅谈排序算法:冒泡排序法和选择排序法的区别
之前学习了冒泡排序法和选择排序法,最近被老师问某个道题用的是什么排序法.自己居然答不出来,才发现自己没有真正弄懂,这两个算法的原理和区别,所以····· 1冒泡排序法 1.1什么是冒泡排序法? 顾名思 ...
- 子集生成的两种方法 (增量构造法 和 位向量法)
该算法来自--刘汝佳的算法竞赛入门经典.书中介绍了两种算法的核心代码,但却没有逐过程详细解说,另初学者看文字时很难看懂 遇到问题,是先要直接研究问题的细节呢还是先把问题搞清楚? 我认为绝对应该先学习如 ...
- 子集生成算法——增量构造法
我的个人博客:逐步前行STEP #思路是一次选出一个元素放入集合中 生成0~n的子集,每次选出最小的值放入集合中,通过从0递增得到下一个位置的值. #include<stdio.h> #i ...
- 子集生成-增量构造法||位向量法
#include<bits/stdc++.h> using namespace std; int arr[25]; void print_subset(int n,int* A,int c ...
- 算法竞赛入门经典读书笔记(四)7.3子集生成
输入一个数n,输出集合0,1,2,3,n-1的全部子集 方法一:增量构造法: #include <iostream> using namespace std; void print_sub ...
- 子集生成(二进制法,逐步生成,递归增量)
子集生成的三种方法 二进制法 1.不算空集,共有2^n-1个子集 2.对应二进制数的第N为1,则将A[N]选中,否则不选 逐步生成法 对每一个元素进行处理,每一个元素都可以被选中或者不选中 递归增量构 ...
- 子集构造法和含有空串的子集构造法
子集构造法 子集构造法很简单. 消除空转移子集构造法 Design 闭包是自己+接受空串能到达的状态. DFA的开始状态时NFA的闭包 3.识别的语言:(a+c+e)(a+c+e)b+(a+c+e) ...
最新文章
- 多样性计算时代,怎样的技术生态才能满足发展需求
- 用Visio制作周行事历
- python数据库-mysql
- docker for windows could not read CA certificate【转】
- 数据库原理上机实验内容报告代码
- as it exceeds the max of 500KB._IT狂人第一季 | 如何考察员工
- 关于多条id相同,只取其中一条记录的sql语句
- sqlmap第一次打靶成功
- android+对象池使用,Android开发中对高并发对象池的重复利用
- 时间序列分析(3)| ARMA模型的拟合
- Win10中允许UWP应用走代理的操作方法
- 微信无法直接打开淘宝链接是怎么回事?
- [Objective-C]第一天
- vue $confirm 自定义图标及修改图标颜色
- 机器学习简易入门-附推荐学习资料
- ArtWork+并查集二维
- RTP/RTSP/RTCP 协议详解
- 提交到GitHub错误:src refspec 分支名 does not match any
- DFD图转换成SC图
- 5G图传设备VR+5G直播4K+5G直播