上一篇文章也讲过,find()函数只能处理简单类型的内容,也就是缺省类型,如果你想用一个自定义类型的数据作为查找依据则会出错!这里将讲述另外一个函数find_if()的用法

这是find()的一个更强大的版本。这个例子演示了find_if(),它接收一个函数对象的参数作为参数, 并使用它来做更复杂的评价对象是否和给出的查找条件相付。
假设我们的list中有一些按年代排列的包含了事件和日期的记录。我们希望找出发生在1997年的事件。

代码如下:

  1. //----------------------------------------------------------------------------------------
  2. //      Desc:       STL_find_if()_How to find things in an STL list MkII
  3. //      Author:     pigfly
  4. //      Data:       2010.12.01
  5. //      Copyright (C) 2010 pigfly
  6. //----------------------------------------------------------------------------------------
  7. #include <iostream>
  8. #include <string>
  9. #include <list>
  10. #include <algorithm>
  11. using namespace std;
  12. class EventIsIn1997 {
  13. public:
  14. bool operator () (string& EventRecord) {
  15. // year field is at position 12 for 4 characters in EventRecord
  16. return EventRecord.substr(11,4)=="1997";
  17. //return this->substr(11,4)=="1997"
  18. }
  19. };
  20. int main (void) {
  21. list<string> Events;
  22. // string positions 0123456789012345678901234567890123456789012345
  23. Events.push_back("07 January 1995 Draft plan of house prepared");
  24. Events.push_back("07 February 1996 Detailed plan of house prepared");
  25. Events.push_back("10 January 1997 Client agrees to job");
  26. Events.push_back("15 January 1997 Builder starts work on bedroom");
  27. Events.push_back("30 April 1997 Builder finishes work");
  28. list<string>::iterator EventIterator = find_if (Events.begin(), Events.end(), EventIsIn1997());
  29. // find_if completes the first time EventIsIn1997()() returns true
  30. // for any object. It returns an iterator to that object which we
  31. // can dereference to get the object, or if EventIsIn1997()() never
  32. // returned true, find_if returns end()
  33. if (EventIterator==Events.end()) {
  34. cout << "Event not found in list" << endl;
  35. }
  36. else {
  37. cout << *EventIterator << endl;
  38. }
  39. }

输出:

10 January 1997 Client agrees to job

这里请注意,find_if()的第三个参数是EventIsIn1997(),它是个仿函数,接收一个string对象,在运算符()的内部定义我所要的查找条件,本例的查找条件是:EventRecord.substr(11,4)=="1997",注意,这里的仿函数返回类型必须是bool类型,这客观反应在find_if()函数查找过程中的是否匹配!

下面我们在看看,数据类型是自定义的结构体的查找过程:

代码:

  1. //----------------------------------------------------------------------------------------
  2. //      Desc:       STL_find_if() used in vector container, struct data
  3. //      Author:     pigfly
  4. //      Data:       2010.12.01
  5. //      Copyright (C) 2010 pigfly
  6. //----------------------------------------------------------------------------------------
  7. #include <iostream>
  8. #include <vector>
  9. #include <string>
  10. #include <algorithm>
  11. using namespace std;
  12. struct value_t
  13. {
  14. int a;
  15. int b;
  16. };
  17. class vector_finder
  18. {
  19. public:
  20. vector_finder( const int a, const int b ) :m_v_a(a),m_v_b(b){}
  21. bool operator ()( vector<struct value_t>::value_type &value)
  22. {
  23. return (value.a==m_v_a)&&(value.b = m_v_b);
  24. }
  25. private:
  26. int m_v_a;
  27. int m_v_b;
  28. };
  29. int main()
  30. {
  31. vector<value_t> my_vector;
  32. value_t my_value;
  33. my_value.a = 11; my_value.b = 1001;
  34. my_vector.push_back(my_value);
  35. my_value.a = 12; my_value.b = 1002;
  36. my_vector.push_back(my_value);
  37. my_value.a = 13; my_value.b = 1003;
  38. my_vector.push_back(my_value);
  39. my_value.a = 14; my_value.b = 1004;
  40. my_vector.push_back(my_value);
  41. vector<value_t>::iterator it = find_if( my_vector.begin(), my_vector.end(), vector_finder(13,1003));
  42. if( it == my_vector.end() )
  43. cout<<"not found!"<<endl;
  44. else
  45. cout<<"found value a:"<<(*it).a <<", b:"<<(*it).b<<endl;
  46. return 0;
  47. }

输出:

found value a:13, b:1003

在这里,我们同样构造了一个仿函数,也就是class vector_finder,也就是vector_finder()函数,注意它的结构与我们要查找的结构体之间的关系,我们发现,它们是非常相象的。

这里的重点就在于class vector_finder的构造!

下面再看看,在map容器中的应用:

代码

  1. //----------------------------------------------------------------------------------------
  2. //      Desc:       STL_find_if() used in map container, string data
  3. //      Author:     pigfly
  4. //      Data:       2010.12.01
  5. //      Copyright (C) 2010 pigfly
  6. //----------------------------------------------------------------------------------------
  7. #include <iostream>
  8. #include <map>
  9. #include <string>
  10. #include <algorithm>
  11. using namespace std;
  12. class map_finder
  13. {
  14. public:
  15. map_finder( string cmp_string ) : m_string(cmp_string) {}
  16. bool operator () (const map<int,string>::value_type pair)
  17. {
  18. return pair.second == m_string;
  19. }
  20. private:
  21. string m_string;
  22. };
  23. int main()
  24. {
  25. map<int ,string> my_map;
  26. my_map.insert( make_pair(10,"china"));
  27. my_map.insert( make_pair(20,"usa"));
  28. my_map.insert( make_pair(30,"english"));
  29. my_map.insert( make_pair(40,"hongkong"));
  30. map<int,string>::iterator it = find_if(my_map.begin(),my_map.end(),map_finder("english"));
  31. if( it == my_map.end() )
  32. cout<<"not found!"<<endl;
  33. else
  34. cout<<"found key:"<<(*it).first<<", value:"<<(*it).second<<endl;
  35. return 0;
  36. }

输出:

found key:30,vlaue:english

由于这里只是讲究一下find_if()的用法,没有去关心它的细节,如果希望了解更多,比如仿函数的模板原形,甚至整个STL

STL中的find_if函数的更多相关文章

  1. C++STL中的unique函数解析

    一.总述 unique函数属于STL中比较常用函数,它的功能是元素去重.即”删除”序列中所有相邻的重复元素(只保留一个).此处的删除,并不是真的删除,而是指重复元素的位置被不重复的元素给占领了(详细情 ...

  2. c++中STL中的next_permutation函数基本用法

    对于next_permutation函数是针对于排列组合问题的库函数,它的排序方式是按照字典的方式排列的·: 如以下代码对于next_permutation函数的初步解释: #include<c ...

  3. 为什么map对象不能使用stl中的sort函数

    STL所提供的各式各样算法中,sort()是最复杂最庞大的一个.这个算法接受两个RandomAccestlerators(随机存取迭代器),然后将区间内的所有元素以渐增方式由小到大重新排列.第二个版本 ...

  4. C++STL中的unique函数

    头文件:#include<iostream> 函数原型:iterator unique(iterator it_1,iterator it_2); 作用:元素去重,即”删除”序列中所有相邻 ...

  5. stl中的for_each() 函数的注意事项

    #include<iostream> using namespace std; #include"vector" #include"algorithm&quo ...

  6. 「STL中的常用函数 容器」

    占个坑,下午在更 二分操作:lower_bound和upper_bound 存图/数列操作:vector容器 全排列:next_permutation和prev_permutation 字符串转数列: ...

  7. STL中一些函数的应用

    1.nth_element():找到第几大的数.用法:nth_element(a,a+k,a+n),返回一个数组a中第k大的数,时间复杂度比较小,头文件#include <algorithm&g ...

  8. STL中的所有算法(70个)

    STL中的所有算法(70个)----9种类型(略有修改by crazyhacking) 参考自: http://www.cppblog.com/mzty/archive/2007/03/14/1981 ...

  9. STL中的算法

    STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baidu.com/ding ...

随机推荐

  1. ASP.NET用SQL Server中的数据来生成JSON字符串

    原文引自:  作者: 缺水的海豚  来源: 博客园  发布时间: 2010-09-21 21:47  阅读: 6136 次  推荐: 0   原文链接   [收藏] 摘要:ExtJs用到的数据内容基本 ...

  2. Smarty中{literal}的使用详解

     {literal} <script>function Login(){ document.LoginForm.submit();}</script>{/literal} == ...

  3. JQuery调用iframe父页面元素与方法

    JQuery操作iframe父页面与子页面的元素与方法 下面简单使用Jquery来操作iframe的一些记录,这个使用纯JS也可以实现. 第一.在iframe中查找父页面元素的方法: $('#id', ...

  4. iOS开发——OC篇&常用关键字的使用与区别

    copy,assign,strong,retain,weak,readonly,readwrite,nonatomic,atomic,unsafe_unretained的使用与区别 最近在学习iOS的 ...

  5. IIS6中ASP.NET实现对静态文件的授权控制

    后台使用html+ashx+js开发 在VS2008调试并未发现问题 发布到IIS6才发现不需要验证也能访问html文件 解决这个问题配置IIS即可了 方法如下: IIS配置:网站->属性-&g ...

  6. ACCESS中类型操作(限制、转换)

    ACCESS如何保留两位小数 1.可以通过修改表结构中字段的“小数位数”即可. 2.可以通过“更新查询”,将所有该字段的值更新为round(字段名,2) ACCESS如何转换类型 每个函数都可以强制将 ...

  7. Javascript图片轮播

    原文链接:http://www.imooc.com/article/7393 编辑HTML代码: <div id="wrap"><!--图片展示区--> & ...

  8. java 双重检查模式

    java 双重检查模式 在并发环境下 兼顾安全和效率 成例(Idiom)是一种代码层次上的模式,是在比设计模式的层次更具体的层次上的代码技巧.成例往往与编程语言密切相关.双重检查成例(Double C ...

  9. 转:MongoDB调查总结

    与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值 ...

  10. 改进基于Boost.Asio的聊天服务

    Boost.Asio是个非常易用的C++异步网络库,官方文档中一个示例是聊天服务,分为chat_message.chat_client.chat_server三个部分.chat_server的启动代码 ...