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例外,因为关联容器中没有这个成员函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

习题七

umask 022 &#xff0c;请描述该命令的含义创建目录时默认的权限为&#xff1a;755 rwxr-xr-x创建文件时默认的权限为&#xff1a;644 rw-r--r--note:创建文件的默认权限是拿掉了X 所以最大为666&#xff0c;而目录最大为777 umask NUM 就是去掉相应的权限转载于:https://blo…

web中的cookie管理

本篇是以JSP为背景介绍&#xff0c;但是在web开发中也是相同的原理。 什么是cookie 由于http是一种无状态的协议&#xff0c;因此服务器收到请求后&#xff0c;只会当做一次新的请求。即便你重复发送了1000次同样的请求&#xff0c;这1000次都属于独立的请求。 这样显然效率很低…

unity怎么设置游戏页面_杭州有没有正规的unity游戏开发培训机构?

现在Unity游戏开发是个火热的行业&#xff0c;薪资待遇比较高&#xff0c;未来的发展方向和前景也比较不错&#xff0c;很多人也都想成为专业Unity游戏开发工程师&#xff0c;学习Unity游戏开发已经成为很多追求更好就业前景的人的选择。学习专业、系统的Unity游戏开发知识并达…

VC++ 使用attributes定义接口

1.定义预处理命令_ATL_ATTRIBUTES 2.在一个全局的Cpp文件里面配置module的attribute [module(dll, uuid "{3845951F-15B8-4286-8E7D-E9D4F5C7B6CE}", name "TestApp")]3.定义接口 [object,uuid("9F414A8A-1D5E-4aff-A60E-CFD65155ABB6"),dual,…

h3c 虚拟服务器 下一跳,H3CNE 312题和313题 直连路由静态路由的下一跳问题

321.在MSR 路由器上看到路由表里有如下显示&#xff1a; Destination/Mask Proto Pre Cost NextHop Interface 127.0.0.0/8 Direct 0 0 127.0.0.1 InLoop0 127.0.0.1/32 Direct 0 0 127.0.0.1 InLoop0 192.168.96.0/19 Direct 0 0 192.168.120.153 S6/0 那么关于目的地321.在MS…

C++成员变量的初始化顺序问题

先来看两道题&#xff1a; // count algorithm example #include <iostream> // std::cout #include <algorithm> // std::count #include <vector> // std::vector using namespace std; class A { public:A() { cout << "in A()&q…

Knockout.Js案例一Introduction

在这第一个教程中,您将体验的一些基本知识构建的web UI Model-View-ViewModel使用knockout.js(MVVM)模式。案例1&#xff1a;添加:data-bind <p>First name: <strong data-bind"text:firstName">1</strong></p><p>Last name: <stro…

C#注册表常用操作

1&#xff1a;加键 改值 Microsoft.Win32.RegistryKey Key Microsoft.Win32.Registry.CurrentUser.CreateSubKey( "Software\Microsoft\Internet Explorer\Main"); Key.SetValue( "Window Title" , value ); Key.Close(); …

谷歌浏览器外贸版_做外贸快两个月,没有单怎么办?

Hello 大家好&#xff0c;我是Jack。今天给大家更新一篇在知乎看到的外贸问题&#xff1a;做外贸快两个月&#xff0c;没有单怎么办?外贸这个话题在知乎算是小众话题了&#xff0c;相比较于职场&#xff0c;英语学习&#xff0c;国际政治&#xff0c;IT等&#xff0c;这些话题…

React Native通信机制详解

http://blog.cnbang.net/tech/2698/ React Native是facebook刚开源的框架&#xff0c;可以用javascript直接开发原生APP&#xff0c;先不说这个框架后续是否能得到大众认可&#xff0c;单从源码来说&#xff0c;这个框架源码里有非常多的设计思想和实现方式值得学习&#xff0c…

C++11系列学习之四----auto

在哪些情况下要申明类型&#xff1a; 定义变量类型 函数返回值&#xff0c;函数参数 表达式返回变量类型 auto关键字原理 在定义变量的时候必须申明类型&#xff0c;c是强语言类型&#xff0c;在编译阶段需要知道类型&#xff0c;这样的好处是程序效率更高&#xff0c;而…

windows 自动copy远程服务器文件

net use h: \\123.45.67.000\T1dbbackup 123456/user:administrator ------远程服务器IP123.45.67.000 。T1dbbackup&#xff1a;共享文件夹 。 h :映射到本机的盘符。 用户名&#xff1a;administrator&#xff0c;密码&#xff1a;123456copy h:\*.* f:\T1DB ------复…

eclipse 不能切换输入法

按了AltShift键&#xff1f;再按一次把EN切换成CN&#xff0c;然后再CtrlShift就可以切换输入法转载于:https://www.cnblogs.com/jiayonghua/p/3413827.html

excel打开2个独立窗口_谢楠称女性独立的不是钱是心 谢楠与吴京婚后生育2个儿子...

近日&#xff0c;在综艺节目《幸福三重奏》 三日谈妻子篇中&#xff0c;谢楠被问到如何看待独立女性时&#xff0c;反问记者会不会问吴京同样的问题&#xff1b;随后回答道&#xff0c;女性独立的不是钱&#xff0c;而是你的心&#xff1b;楠姐的回答超级霸气了&#xff0c;你们…

C++11系列学习之五-------decltype

使用场景 在C中经常要用到很长的变量名&#xff0c;如果已经有变量和你将使用的变量是一个类型&#xff0c;即可使用decltype关键字 来申明一样的类型变量。 decltype原理 返回现有变量类型&#xff0c;decltype是一个关键字&#xff0c;而不是一个函数&#xff0c;这有啥区别…

Linux学习 Unit 9

Unit9.openssh-server1.openssh-server功能&#xff1a;让远程主机可以通过网络访问sshd服务&#xff0c;开始一个安全shell2.客户端连接方式ssh远程主机用户远程主机ip[rootdesktop0 ~]# ssh root172.25.0.11The authenticity of host 172.25.0.11 (172.25.0.11) cant be esta…

2015年创业中遇到的技术问题:41-50

41.Bootstrap换行。col-md-10和col-md-2。这2个div按说应该在一行的&#xff0c;结果col-md-2换行了。看看样式&#xff0c;发现有多余的“margin-left: 1px;"。42.Service实现类定义了一个“自动调度进行刷新”的方法。OverrideScheduled(cron "0 0/10 * * * ? &q…

KMP模板与讲解

读书笔记终于写完了&#xff0c;写一下我对KMP的理解。 KMP的思想就是尽量利用已经得到的信息&#xff0c;来降低时间复杂度&#xff0c;已经得到的信息存放在next数组里。算法确实很难理解&#xff0c;所以很难讲解。。举个例子来说吧。 设字符串是str[]&#xff0c;next[5] …

android 非root app 捕捉系统广播_APP的生死之道

这篇文章主要介绍APP在安卓系统中是怎么被杀死的&#xff0c;按照怎样的一个策略去释放进程&#xff1b;同时介绍一些延长应用存活时间的方案&#xff0c;虽然这个在现在安卓系统上越来越难实现了&#xff0c;但是也是可以稍微了解下&#xff0c;主要也是通过这些hack的方案更好…

C++11系列学习之六-----for

前言C11这次的更新带来了令很多C程序员期待已久的for range循环&#xff0c;每次看到javascript&#xff0c; lua里的for range&#xff0c;心想要是C能有多好&#xff0c;心里别提多酸了。这次C11不负众望&#xff0c;再也不用羡慕别家人的for range了。使用场景ex1&#xff1…