C++ STL的查找算法
假设你有一个序列容器,或者有一对迭代器标识了一个区间,现在你希望在容器中查找一些信息,这样的查找工作如何进行呢?你的选择往往是:
count,count_if,find,find_if,binary_search,lower_bound,upper_bound,equal_range.该如何选择呢?
现在,我们假设你有了一对迭代器,他们指定了一个被选择的区间。
在选择具体的策略时,需要考虑由迭代器指定的区间是否是排序的,这是一个至关重要的决定条件。
未排序区间
如果迭代器并没有指定一个排序的区间,那么你的选择是count/count_if,find/find_if.这些算法提供线性时间的效率。
count
问题:
区间中是否有某个特定的值?如果有,有几个?
用法:
list<Widget> lw;
Widget w;
...
if(count(lw.begin(),lw.end(),w)!=0)//w在lw中
{
....
}
else//w不在lw中
{
.....
}
这段代码演示了一种常见的习惯用法:将count用在存在性测试。count返回0或者一个正整数
find
问题:
区间中是否有某个特定的值?如果有,在哪里?
用法:
if(find(lw.begin(),lw.end(),w)!=lw.end())//存在w
{
...
}
else//不存在w
{
...
}
从存在性测试的角度来看,count的习惯用法较为容易编码一些,但同时,他的效率要差一些。因为find一旦找到第一个匹配的结果后马上返回,而count必须到达区间的末尾,以便找到所有的匹配。
排序区间
对于已经排序的区间,我们将使用binary_search、lower_bound、upper_bound、equal_range.它们以对数时间运行。其实他们的背后是二分查找法。
binary_search
问题:
binary_search仅仅返回的是一个bool值:是否找到了特定的值
用法:
vector<Widget> vw;
...
sort(vw.begin(),vw.end());
Widget w;
...
if(binary_search(vw.begin(),vw.end(),w))
{
...//w在vw中
}
else
{
...//w不在vw中
}
lower_bound
问题:
这个值在区间中吗?如果在,那么第一个拷贝在哪里?如果不在,他该往哪里插入?
用法
我们仅将lower_bound用在下面的情景中:
假设我们有一个Timestamp类和一个存放Timestamp的vector,并且这个vector已经排过序,其中老的时间排在前面。
class Timestamp{...};
bool operator<(const Timestamp& lhs,const Timestamp& rhs);//判断lhs是否在rhs之前
vector<Timestamp> vt;
...
sort(vt.begin(),vt.end());
现在假设有一个特殊的时间戳,ageLimit,我们希望删除所有在ageLimit之前的Timestamp对象。在这种情况下,我们并不想找到
该区间中与ageLimit等价的Timestamp类,因为该区间中可能根本没有与它等价的对象。我们其实想在vt中找到一个位置:第一个不比ageLimit老的位置。这是非常容易的,因为lower_bound给我们一个准确地答案:
Timestamp ageLimit;
...
vt.erase(vt.begin(),lower_bound(vt.begin(),vt.end(),ageLimit));//删除所有在ageLimit之前的对象
那么如果我们想删除那些至少和ageLimit一些老的对象呢?
这就是我们即将看到的upper_bound
upper_bound
问题:
这个值在区间中吗?如果在,那么最后一个拷贝的下一个位置在哪里?如果不在,他该往哪里插入?
用法
同样我们也只考虑以上给出的应用,
代码如下:
vt.erase(vt.begin(),upper_bound(vt.begin(),vt.end(),ageLimit));//从vt中删除所有在ageLimit之前或者与ageLimit等价的对象
我们看到lower_bound与upper_bound的用法与给出的问题,似乎有点不合,实际上,我在这里做了简化,只列出了使用以上两个函数的最常见和最应该使用之处,至于其它,建议参考《Effective STL》45条
equal_range
问题:
这个值在区间中吗?如果在,在哪里?
用法
vector<Widget> vw;
...
sort(vw.begin(),vw.end());
typedef vector<Widget>::iterator VWIter;
typedef pair<VWIter,VWIter> VWIterPair;
VWIterPair p=eauql_range(vw.begin(),vw.end(),w);
if(p.first!=p.second)//如果equal_range返回非空区间,
{ //找到了特定值,p.first指向第一个与w等价的
... //对象,p.second指向最后一个与w等价的对象
} //的下一个位置
else
{
... //没有找到特定值,p.first与p.second都
} //指向w的插入位置
而且,你还可以打印出有多少个这样的对象。
VWIterPair p=eauql_range(vw.begin(),vw.end(),w);
cout<<"There are"<<distance(p.first,p.second)<<"elements in vw equivalent to w.";
注意:
以上我们的方法使用与序列容器如:vector,string,deque,list。
关联容器也有count.find,equal_range,lower_bound,upper_bound成员函数。凡是前面的讨论中建议选择以上算法的,在关联容器中只要使用同名的成员函数即可。只有binary_search例外,因为关联容器中没有这个成员函数。
C++ STL的查找算法相关推荐
- C++ STL 常用查找算法
C++ STL 常用查找算法 adjacent_find() 在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器.否则返回past-the-end. ...
- C++STL常用查找算法
C++STL常用查找算法 学习目标 算法简介 find 功能描述 函数原型 示例 总结 find_if 功能描述 函数原型 示例 总结 adjacent_find 功能描述 函数原型 示例 总结 bi ...
- [C++STL]常用查找算法
代码如下: #include <iostream> #include <algorithm> #include <vector> #include <stri ...
- c++中STL的常用算法---2(遍历算法,查找算法)
算法概述 算法主要由头文件组成 是所有STL头文件中最大的一个,其中常用的功能涉及到比较,交换,查找,遍历,复制,修改,反转,排序,合并等 体积很小,只包括在几个序列容器上进行的简单运算的模板函数 定 ...
- STL常用的查找算法
常用的查找算法 adjacent_find() binary_search count() count_if() find() find_if() adjacent_find() 在iterator对 ...
- STL算法——常用查找算法(find、find_if、adjacent_find、binary_search、count、count_if)
5.2 常用查找算法 学习目标: 掌握常用的查找算法 算法简介: find //查找元素 find_if //按条件查找元素 adjacent_find //查找相邻重复元素 binary_searc ...
- stl非变易算法(二)
这里接着上篇stl非变易算法(一)进行总结.主要解析算法函数count.count_if.mismatch.equal.search.search_n以及find_end.给出算法函数的实现及測试用例 ...
- C++STL常用遍历算法
C++STL常用遍历算法 概述 学习目标 算法简介 for_each 功能描述 函数原型 示例 总结 transform 功能描述 函数原型 示例 总结 概述 算法主要是由头文件<algorit ...
- c++中STL的常用算法--1(函数对象,谓词,内建函数对象)
函数对象 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载"()"操作符,使得 ...
最新文章
- 【Mysql 学习路线图】
- viewDidLoad, viewWillDisappear, viewWillAppear等区别及各自的加载顺序
- Oracle执行计划显示
- [JavaWeb-JavaScript]JavaScript注释数据类型
- LeaFlet学习之聚合效果
- LeetCode2. 两数相加
- django和mysql
- sql server使用的注意点及优化点 自备
- 持续集成CI, 持续部署CD, 持续交付CD要点
- 手把手教你调用微信扫一扫,三分钟包会
- 计算机教育部一级学科,教育部学科门类,一级学科有多少个?
- matlab phandom,DOMFluor 用Matlab编写的三维荧光分析工具 联合开发网 - pudn.com
- c语言pic延时1ms程序,几个延时子程序
- 斐那契波黄金数列MATLAB,广义斐波那契数列的性质及推广
- 网站加速教程--提升性能的同时节约10倍成本
- 3g无线图传点到点模式与服务器模式比较,4G网络的几个关键技术指标 - 3G和4G LTE网络架构之间的区别...
- Gentoo 教程:基本系统安装
- 数据结构概述3 对称矩阵、树和二叉树
- Rainbond插件体系设计简介
- 4-3 Coursera吴恩达《卷积神经网络》 第三周课程笔记-目标检测
热门文章
- Python爬虫学习笔记1:request、selenium、ChromeDrive、GeckoDriver等相关依赖安装
- Feature Preprocessing on Kaggle
- WPF 带CheckBox、图标的TreeView
- linear-gradient线性渐变
- Qt的元对象(Meta-Object)系统简介(转)
- win7无法将应用程序锁定到任务栏的几种解决方法
- 企业云存储:为什么中大型企业偏爱自建私有云?
- 1月28日云栖精选夜读 | 终于等到你!阿里正式向 Apache Flink 贡献 Blink 源码
- 杨浦区阜盛农民工子弟小学见闻
- 使用glew和glad 新建窗口