回顾学习find和find_if, 网上查了一下资料,这里记录一下。

STL的find,find_if函数提供了一种对数组、STL容器进行查找的方法。使用该函数,需 #include <algorithm>
我们查找一个list中的数据,通常用find(),例如:

1、find

using namespace std;
int main()
{
    list<int> lst;
    lst.push_back(10);
    lst.push_back(20);
    lst.push_back(30);
    list<int>::iterator it = find(lst.begin(), lst.end(), 10); // 查找list中是否有元素“10”
    if (it != lst.end()) // 找到了
    {
        // do something 
    }
    else // 没找到
    {
        // do something
    }
    return 0;
}

那么,如果容器里的元素是一个类呢?例如,有list<CPerson> ,其中CPerson类定义如下:
class CPerson
{
public:
    CPerson(void); 
    ~CPerson(void);

bool CPerson::operator==(const CPerson &rhs) const
    {
        return (age == rhs.age);
    }

public:
    int age; // 年龄
};

那么如何用find()函数进行查找呢?这时,我们需要提供一个判断两个CPerson对象“相等”的定义,find()函数才能从一个list中找到与指定的CPerson“相等”的元素。
      这个“相等”的定义,是通过重载“==”操作符实现的,我们在CPerson类中添加一个方法,定义为:
bool operator==(const CPerson &rhs) const;
      实现为:
bool CPerson::operator==(const CPerson &rhs) const
{
    return (age == rhs.age);
}

然后我们就可以这样查找(假设list中已经有了若干CPerson对象)了:

list<CPerson> lst;
// 向lst中添加元素,此处省略

CPerson cp_to_find; // 要查找的对象
cp_to_find.age = 50;
list<CPerson>::iterator it = find(list.begin(), list.end(), cp_to_find); // 查找

if (it != lst.end()) // 找到了
{
}
else // 没找到
{
}
这样就实现了需求。

2、find_if

有人说,如果我有自己定义的“相等”呢?例如,有一个list<CPerson*>,这个list中的每一个元素都是一个对象的指针,我们要在这个list中查找具有指定age的元素,找到的话就得到对象的指针。
      这时候,你不再能像上面的例子那样做,我们需要用到find_if函数,并自己指定predicate function(即find_if函数的第三个参数,请查阅STL手册)。先看看find_if函数的定义:

template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator _First, InputIterator _Last, Predicate _Pred);

Parameters
_First
An input iterator addressing the position of the first element in the range to be searched.
_Last
    An input iterator addressing the position one past the final element in the range to be searched.
_Pred
    User-defined predicate function object that defines the condition to be satisfied by the element being searched for. A predicate takes single argument and returns true or false.

我们在CPerson类外部定义这样一个结构体:
typedef struct finder_t
{
    finder_t(int n) : age(n) { } 
    bool operator()(CPerson *p) 
    { 
        return (age == p->age); 
    } 
    int age;
}finder_t;

然后就可以利用find_if函数来查找了:
list<CPerson*> lst;
// 向lst中添加元素,此处省略

list<CPerson*>::iterator it = find_if(lst.begin(), lst.end(), finder_t(50)); // 查找年龄为50的人
if (it != lst.end()) // 找到了
{
    cout << "Found person with age : " << (*it)->age;
}
else // 没找到
{
    // do something
}

2.1、例子1

map<int, char*> mapItems;
auto it = find_if(mapItems.begin(), mapItems.end(), [&](const pair<int, char*> &item) {
    return item->first == 0/*期望值*/;
});

2.2、例子2

typedef struct testStruct
{
    int a;

    int b;
}
testStruct;

vector<testStruct> testStructVector;
auto itrFind = find_if(testStructVector.begin(), testStructVector.end(), [](testStruct myStruct)
{
     return myStruct.a > 2 && myStruct.b < 8;
});
 
if(itrFind != testStructVector.end())
        TRACE("found!");
else
        TRACE("not found!");

2.3、例子3

#include <string>
#include <algorithm>
class map_value_finder
{
public:
    map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}
    bool operator ()(const std::map<int, std::string>::value_type &pair)
    {
        return pair.second == m_s_cmp_string;
    }
private:
    const std::string &m_s_cmp_string;                    
};
 
int main()
{
    std::map<int, std::string> my_map;
    my_map.insert(std::make_pair(10, "china"));
    my_map.insert(std::make_pair(20, "usa"));
    my_map.insert(std::make_pair(30, "english"));
    my_map.insert(std::make_pair(40, "hongkong"));    
    
    std::map<int, std::string>::iterator it = my_map.end();
    it = std::find_if(my_map.begin(), my_map.end(), map_value_finder("English"));
    if (it == my_map.end())
       printf("not found\n");       
    else
       printf("found key:%d value:%s\n", it->first, it->second.c_str());
       
    return 0;        
}

2.4、例子4

struct map_value_finder  
{  
public:  
    map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){}  
    bool operator ()(const std::map<int, std::string>::value_type &pair)  
    {  
        return pair.second == m_s_cmp_string;  
    }  
private:  
    const std::string &m_s_cmp_string;                      
};

bool funddd(const std::map<int, std::string>::value_type &pair)  
{  
    return pair.second == "english";  

  
int main()  
{  
    std::map<int, std::string> my_map;  
    my_map.insert(std::make_pair(10, "china"));  
    my_map.insert(std::make_pair(20, "usa"));  
    my_map.insert(std::make_pair(30, "english"));  
    my_map.insert(std::make_pair(40, "hongkong"));      
      
    std::map<int, std::string>::iterator it = my_map.end();  
    it = std::find_if(my_map.begin(), my_map.end(), funddd);  
    if (it == my_map.end())  
       printf("not found\n");         
    else  
       printf("found key:%d value:%s\n", it->first, it->second.c_str());

getchar();  
    return 0;          
}

下面再说绑定器bind:

STL中的绑定器有类绑定器和函数绑定器两种,类绑定器有binder1st和binder2nd,而函数绑定器是bind1st和bind2nd,他们的基本目的都是用于构造一个一元的函数对象。比如这里我们可以利用bind2nd通过绑定二元函数对象中的第二个参数的方式来实现二元谓词向一元谓词的转换。

struct compare: binary_function<A, string,bool> {
    bool operator()( A &value, string str) const
    {
        if (value.GetStr()== str)
            return true;
        else
            return false;
    }
};

示例:
vector<A>::iterator t=find_if(a.begin(),a.end(),bind2nd(compare(), ”33″));

无论是用vector的循环还是find_if泛型算法,在性能和代码复杂度上面都有一定得权衡,至于在实际应用中,还是需要具体问题具体分析的。

以下泛型模板

现在还是迷糊的,下面是自己在项目中看到的师傅写的一个比较实用的方法:

template<typename T> bool compare_no(const T* s1 , const T* s2)
{  
    return strcmp(s1->no, s2->no) == 0;
}

template<typename T> bool less_no(const T* s1 , const T* s2)
{
    return strcmp(s1->no, s2->no) < 0;
}

template<typename T> bool compare_id(const T* s1 , const T* s2)
{
    return s1->id == s2->id;
}

template<typename T> bool less_id(const T* s1 , const T* s2)
{
    return s1->id < s2->id;
}

//排序
std::sort(vct_device.begin(), vct_device.end(), less_id<ST_DEVICE>);
std::sort(vct_camer.begin(), vct_camer.end(), less_no<ST_CAMERA>);

//通过编号查找ID

vector<ST_CAMERA*>::iterator it_cam;
ST_CAMERA tmp_cam;
strcpy(tmp_cam.no, "888888");
it_cam = std::find_if(vct_camer.begin(),vct_camer.end(),bind2nd(ptr_fun(compare_no<ST_CAMERA>), &tmp_cam));
if (it_cam != vct_camer.end())
     返回值channel = (*it_cam)->channel;

//通过ID查找编号

vector<ST_CAMERA*>::iterator it_cam;
ST_CAMERA tmp_cam;
int camid = 0;
tmp_cam.id = 3;
it_cam = std::find_if(vct_camer_secd.begin(), vct_camer_secd.end(), bind2nd(ptr_fun(compare_id<ST_CAMERA>), &tmp_cam));
if (it_cam == vct_camer_secd.end())
       返回值strcpy(camera,(*it_cam)->no);

https://blog.csdn.net/bobodem/article/details/49386131

C++11 find和find_if的用法相关推荐

  1. SwiftUI 内功教程之Closures 11 Escaping Closures及经典用法

    SwiftUI 内功教程之Closures 11 Escaping Closures及经典用法 什么是闭包 闭包是独立的功能块,可以在代码中传递和使用.Swift中的闭包类似于C和Objective- ...

  2. C++11中=delete的巧妙用法

    C++11中,当我们定义一个类的成员函数时,如果后面使用"=delete"去修饰,那么就表示这个函数被定义为deleted,也就意味着这个成员函数不能再被调用,否则就会出错. #i ...

  3. Mysql(11)——group by的用法

    group by的作用是将字段中相等的分为一组: (1)直接用法 如上:可以见得:将两种数据分了出来:0和1. (2)与group_concat()联用 group_concat()的作用是统计每个分 ...

  4. vector中find和find_if的用法

    今天郁闷写大作业中.唉..每次写都tm暴力遍历.有stl你用毛遍历啊.现在记下来.再遍历就剁手吧.(- -!) stl包括容器.迭代器和算法: 容器 用于管理一些相关的数据类型.每种容器都有它的优缺点 ...

  5. C++11 参数绑定-bind函数用法

    lambda表达式:https://blog.csdn.net/readyone/article/details/110874546 https://blog.csdn.net/readyone/ar ...

  6. c++11中的for简化用法

    1.序列for循环 map<string,int> m{{"a",1},{"b",2},{"c",3}} for(auto p: ...

  7. C++11中shared_ptr智能指针用法

    #include <memory> #include <iostream> using namespace std;class Test{//外部类及函数不可访问成员变量等 / ...

  8. c++ stl find和find_if, 迭代器

    c++之使用emplace_back()取代push_back() https://www.cnblogs.com/ChrisCoder/p/9919646.html C++ STL迭代器原理和实现_ ...

  9. 【C++11】lambda函数及其基本用法

    目录 即看即用 详情 基本概念和用法 捕获列表 lambda表达式的类型 即看即用 语法: [capture](parameters)->return-type {body} []叫做捕获说明符 ...

最新文章

  1. 创新实训个人记录:metric k-center
  2. 项目管理一般知识:单个项目的管理过程
  3. [云炬创业学笔记]第二章决定成为创业者测试10
  4. 关于ubantu软件包的相关记录
  5. hotspot jvm_在Hotspot JVM中跟踪过多的垃圾收集
  6. 千兆交换机下面可以接多少层交换机_视频监控系统如何选择网络交换机
  7. ThinkPHP3.2.3分页中文参数乱码问题及解决
  8. JavaScript 常用Array、String方法
  9. 【JSOI2014】【BZOJ5039】序列维护(线段树模板)
  10. jQuery——入口函数
  11. python抽取html中的链接
  12. w10如何共享计算机硬盘,w10共享盘怎么设置_win10如何共享硬盘
  13. 枚举类中的valueOf用法
  14. android导航功能介绍,百度导航功能介绍
  15. matlab 阶梯形矩阵,求化矩阵为阶梯型矩阵的代码(不是行最简函数rref)
  16. awscli配置Access key ID和Secret access key
  17. MultiPath: Multiple Probabilistic Anchor Trajectory Hypotheses for Behavior Prediction
  18. WEB工程师和设计师必学的10个IOS 8新鲜改变
  19. linux getchar函数使用
  20. the work directory /tmp/ oracle,Oracle升级问题总结

热门文章

  1. 虚幻4 UE4 蓝图C++混合编程
  2. VBA WORD 段落前加空行
  3. 【译】 WebP 支持:超出你想象
  4. DNS服务器未响应,电脑网页打不开
  5. java输出每一列数据左对齐_Java(或Excel) - 如何对齐乱序的列数据
  6. PSpice中VPulse的设置问题
  7. France beat Croatia 4-2 in World Cup final
  8. 英伟达Isaac介绍
  9. MySQL:使用PMM进行性能监控
  10. 软件测试常用的工具都在这里了