C++ STL算法系列2---find ,find_first_of , find_if , adjacent_find的使用
一.find运算
假设有一个int型的vector对象,名为vec,我们想知道其中是否包含某个特定值。
解决这个问题最简单的方法时使用标准库提供的find运算:

- 1 // value we'll look for
- 2 int search_value = 42;
- 3
- 4 //call find to see if that value is present
- 5 vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value);
- 6
- 7 //report the result
- 8 cout<<"The value "<<search_value
- 9 <<(result == vec.end() ? " is not present" : "is present")
- 10 <<endl;

具体实现代码:

- 1 #include<iostream>
- 2 #include<vector>
- 3 #include<algorithm>
- 4 using namespace std;
- 5
- 6 int main()
- 7 {
- 8 // value we'll look for
- 9 int search_value = 42;
- 10 int ival;
- 11 vector<int> vec;
- 12
- 13 while(cin>>ival)
- 14 vec.push_back(ival);
- 15
- 16 cin.clear();
- 17
- 18 //call find to see if that value is present
- 19 vector<int>::const_iterator result = find(vec.begin() , vec.end() , search_value);
- 20
- 21 //report the result
- 22 cout<<"The value "<<search_value
- 23 <<(result == vec.end() ? " is not present" : "is present")
- 24 <<endl;
- 25
- 26 return 0;
- 27 }

接下来再举一个例子:

- 1 #include <algorithm>
- 2 #include <list>
- 3 #include <iostream>
- 4
- 5 using namespace std;
- 6
- 7 int main()
- 8 {
- 9 list<int> ilist;
- 10 for (size_t i = 0; i < 10; ++i)
- 11 {
- 12 ilist.push_back(i+1);
- 13 }
- 14
- 15 ilist.push_back(10);
- 16
- 17 list<int>::iterator iLocation = find(ilist.begin(), ilist.end(), 10); //find操作查找等于10的元素,并返回指向该元素的迭代器,如果没有找到,返回指向集合最后一个元素的迭代器
- 18
- 19 if (iLocation != ilist.end())
- 20 {
- 21 cout << "找到元素 10" << endl;
- 22 }
- 23
- 24 cout << "前一个元素为:" << *(--iLocation) << endl;
- 25
- 26 return 0;
- 27 }

类似地,由于指针的行为与作用在内置数组上的迭代器一样,因此也可以使用find来搜索数组:
- 1 int ia[6] = {27 , 210 , 12 , 47 , 109 , 83};
- 2 int search_value = 83;
- 3 int *result = find(ia , ia + 6 , search_value);
- 4 cout<<"The value "<<search_value
- 5 <<(result == ia + 6 ? " is not present" : "is present")
- 6 <<endl;
如果需要传递一个子区间,则传递指向这个子区间的第一个元素以及最后一个元素的下一位置的迭代器(或指针)。
例如,在下面对find函数的调用中,只搜索了ia[1]和ia[2]:
- //only search elements ia[1] and ia[2]
- int *result = find(ia + 1 , ia + 3 , search_value);
二.find_first_of的使用
除了find之外,标准库还定义了其他一些更复杂的查找算法。当中的一部分类似string类的find操作,其中一个是find_first_of函数。
这个算法带有两对迭代器参数来标记两端元素范围:第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素。如果找不到匹配元素,则返回第一个范围的end迭代器。
假设roster1和roster2是两个存放名字的list对象,可使用find_first_of统计有多少个名字同时出现在这两个列表中:

- 1 size_t cnt = 0;
- 2 list<string>::iterator it = roster1.begin();
- 3
- 4 // look in roster1 for any name also in roster2
- 5 while((it = find_first_of(it , roster1.end() , roster2.begin() , roster2.end())) != roster1.end())
- 6 {
- 7 ++cnt;
- 8 // we got a match , increment it to look in the rest of roster1
- 9 ++it;
- 10 }
- 11 cout<<"Found "<<cnt
- 12 <<" names on both rosters "<<endl;

调 用find_first_of查找roster2中的每个元素是否与第一个范围内的元素匹配,也就是在it到roster1.end()范围内查找一个元 素。该函数返回此范围内第一个同时存在于第二个范围中的元素。在while的第一次循环中,遍历整个roster1范围。第二次以及后续的循环迭代则只考 虑roster1中尚未匹配的部分。
循环条件检查find_first_of的返回值,判断是否找到匹配的名字。如果找到一个匹配,则使计 数器加1,同时给it加1,使它指向roster1中的下一个元素。很明显可知,当不再有任何匹配时,find_first_of返回 roster1.end(),完成统计。
find_first_of,带有两对迭代器参数。每对迭代器中,两个参数的类型必须精确匹配,但不要求两对之间的类型匹配。特别是,元素可存储在不同类型的序列中,只要这两个序列的元素可以比较即可。
在 上述程序中,roster1和roster2的类型不必精确匹配:roster1可以使list对象,而roster2则可以使vector对象、 deque对象或者是其他后面要学到的序列。只要这两个序列的的元素可使用相等(==)操作符进行比较即可。如果roster1是list< string>对象,则roster2可以使vector<char*>对象,因为string标准库为string对象与char* 对象定义了相等(==)操作符。
三.find_if的使用
find_if算法 是find的一个谓词判断版本,它利用返回布尔值的谓词判断pred,检查迭代器区间[first, last)上的每一个元素,如果迭代器iter满足pred(*iter) == true,表示找到元素并返回迭代器值iter;未找到元素,则返回last。
find_if :在序列中找符合某谓词的第一个元素。
函数原型为:
- 1 template<class InputIterator, class Predicate>
- 2 InputIterator find_if(
- 3 InputIterator _First,
- 4 InputIterator _Last,
- 5 Predicate _Pred
- 6 );
举个例子说明如下:

- 1 #include <algorithm>
- 2 #include <vector>
- 3 #include <iostream>
- 4
- 5 using namespace std;
- 6
- 7 //谓词判断函数 divbyfive : 判断x是否能5整除
- 8 bool divbyfive(int x)
- 9 {
- 10 return x % 5 ? 0 : 1;
- 11 }
- 12
- 13 int main()
- 14 {
- 15 /*
- 16 //初始vector : 方式一
- 17 //使用下标方式来操作vector
- 18 //vector随机访问方便,但插入、删除操作效率非常低
- 19 vector<int> iVect(20);
- 20
- 21 for(size_t i = 0; i < iVect.size(); ++i) //注意:size_t
- 22 {
- 23 iVect[i] = (i+1) * (i+3);
- 24 }
- 25
- 26 */
- 27 //初始vector :方式二
- 28 vector<int> iVect;
- 29 for(vector<int>::size_type i = 0 ; i != 20 ; ++i)
- 30 iVect.push_back((i+1) * (i + 3));
- 31
- 32
- 33 //输出vector里的元素
- 34 for(vector<int>::iterator iter = iVect.begin() ; iter != iVect.end() ; ++iter)
- 35 cout<<*iter<<" ";
- 36 cout<<endl;
- 37
- 38
- 39 vector<int>::iterator iLocation;
- 40 iLocation = find_if(iVect.begin(), iVect.end(), divbyfive);
- 41
- 42 if (iLocation != iVect.end())
- 43 {
- 44 cout << "第一个能被5整除的元素为:"
- 45 << *iLocation << endl //打印元素:15
- 46 << "元素的索引位置为:"
- 47 << iLocation - iVect.begin() << endl; //打印索引位置:2
- 48 }
- 49
- 50 return 0;
- 51 }

四. adjacent_find算法
adjacent_find算法用于查找相等或满足条件的邻近元素对。其有两种函数原型:一种在迭代器区间[first , last)上查找两个连续的元素相等时,返回元素对中第一个元素的迭代器位置。另一种是使用二元谓词判断binary_pred,查找迭代器区间 [first , last)上满足binary_pred条件的邻近元素对,未找到则返回last。
原型:

- 1 <strong>template<class ForwardIterator>
- 2 ForwardIterator adjacent_find(
- 3 ForwardIterator _First,
- 4 ForwardIterator _Last
- 5 );
- 6 template<class ForwardIterator , class BinaryPredicate>
- 7 ForwardIterator adjacent_find(
- 8 ForwardIterator _First,
- 9 ForwardIterator _Last,
- 10 BinaryPredicate _Comp
- 11 );
- 12 </strong>

举例如下:

- 1 #include <algorithm>
- 2 #include <list>
- 3 #include <iostream>
- 4
- 5 using namespace std;
- 6
- 7 //判断X和y是否奇偶同性
- 8 bool parity_equal(int x, int y)
- 9 {
- 10 return (x - y) % 2 == 0 ? 1 : 0;
- 11 }
- 12
- 13 int main()
- 14 {
- 15 //初始化链表
- 16 list<int> iList;
- 17 iList.push_back(3);
- 18 iList.push_back(6);
- 19 iList.push_back(9);
- 20 iList.push_back(11);
- 21 iList.push_back(11);
- 22 iList.push_back(18);
- 23 iList.push_back(20);
- 24 iList.push_back(20);
- 25
- 26 //输出链表
- 27 list<int>::iterator iter;
- 28 for(iter = iList.begin(); iter != iList.end(); ++iter)
- 29 {
- 30 cout << *iter << " ";
- 31 }
- 32 cout << endl;
- 33
- 34 //查找邻接相等的元素
- 35 list<int>::iterator iResult = adjacent_find(iList.begin(), iList.end());
- 36 if (iResult != iList.end())
- 37 {
- 38 cout << "链表中第一对相等的邻近元素为:" << endl;
- 39 cout << *iResult++ << endl;
- 40 cout << *iResult << endl;
- 41 }
- 42
- 43 //查找奇偶性相同的邻近元素
- 44 iResult = adjacent_find(iList.begin(), iList.end(), parity_equal);
- 45 if (iResult != iList.end())
- 46 {
- 47 cout << "链表中第一对奇偶相同的元素为:" << endl;
- 48 cout << *iResult++ << endl;
- 49 cout << *iResult << endl;
- 50 }
- 51 return 0;
- 52 }
C++ STL算法系列2---find ,find_first_of , find_if , adjacent_find的使用的更多相关文章
- C++ STL算法系列4---unique , unique_copy函数
一.unique函数 类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素. 该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序 ...
- C++ STL算法系列 unique
类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素. 该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序改变了),表示无重复的值 ...
- C++ STL算法系列1---unique , unique_copy函数
一.unique函数 类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素. 该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序 ...
- C++ STL算法系列6---copy函数
现在我们来看看变易算法.所谓变易算法(Mutating algorithms)就是一组能够修改容器元素数据的模板函数,可进行序列数据的复制,变换等. 我们现在来看看第一个变易算法:元素复制算法copy ...
- C++ STL算法系列5---equal() , mismatch()
equal和mismatch算法的功能是比较容器中的两个区间内的元素.这两个算法各有3个参数first1,last1和first2.如果对 于区间[first1,last1)内所有的first1+i, ...
- C++ STL算法系列3---求和:accumulate
该算法在numeric头文件中定义. 假设vec是一个int型的vector对象,下面的代码: //sum the elements in vec starting the summation wit ...
- C++ STL算法系列1---count函数
一.count函数 algorithm头文件定义了一个count的函数,其功能类似于find.这个函数使用一对迭代器和一个值做参数,返回这个值出现次数的统计结果. 编写程序读取一系列int型数据,并将 ...
- C++ STL算法之:copy
C++ STL算法:copy 目录(?)[+] 前面十二个算法所展现的都属于非变易算法(Non-mutating algorithms)系列,现在我们来看看变易算法.所谓变易算法(Mutating a ...
- 实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中推断不等于end())、operator[])
遍历一个vector容器有非常多种方法.使用起来也是仁者见仁. 通过索引遍历: for (i = 0; i<v.size(); i++) { cout << v[i] << ...
随机推荐
- CSS:opacity 的取值范围是 0~1
CSS:opacity 的取值范围是 0~1,难怪设置为 1~100 看不到效果.
- dataURI V.S. CSS Sprites 移动端
英文原文:http://www.mobify.com/blog/css-sprites-vs-data-uris-which-is-faster-on-mobile/ 中文翻译:http://www. ...
- JavaWeb应用开发架构浅谈
本文就我所经历和使用过的技术和框架, 讨论 Java / Javascript 技术组合构成的Web 应用架构. 一. 概述 Web 应用架构可以划分为两大子系统:前端子系统和后台子系统. 前端子系统 ...
- iOS9适配 之 关于info.plist 第三方登录 添加URL Schemes白名单
近期苹果公司iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装. 受此影响,当你的应用在 ...
- ReactiveCocoa常见操作方法介绍/MVVM架构思想
1.ReactiveCocoa常见操作方法介绍. 1.1 ReactiveCocoa操作须知 所有的信号(RACSignal)都可以进行操作处理,因为所有操作方法都定义在RACStream.h中, ...
- StringBuilder和Append的一个程序及一个基础概念
废话少说直接来说:比如在串口数据操作中,我们只想显示串口接收的字符串,好吧你用string[]吧,有多少个字符串(顺便说下二进制在C#中是以字符串形式出现的)就要分配多少个储存空间,自己试下,要你你干 ...
- POJ 3281:Dining(最大流)
http://poj.org/problem?id=3281 题意:有n头牛,f种食物,d种饮料,每头牛有fnum种喜欢的食物,dnum种喜欢的饮料,每种食物如果给一头牛吃了,那么另一个牛就不能吃这种 ...
- HTTP中Get与Post的区别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认 为:一个URL地址,它用于描述一个网络上的资源,而HTT ...
- android通知栏总结
通知消息的发送 12-1:消息管理者 NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION ...
- poj 1091 跳蚤
跳蚤 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8482 Accepted: 2514 Description Z城 ...