首页 > 编程语言 >c++中的查找list元素

c++中的查找list元素

时间:2024-04-13 15:57:16浏览次数:16  
标签:std map const list c++ 查找 end find

回顾学习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类外部定义这样一个结构体:

class 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 // it == lst.end() 没找到
{
    // 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/zzhongcy/article/details/87709685

复制链接:https://www.cnblogs.com/ssvip/p/14718943.html

标签:std,map,const,list,c++,查找,end,find
From: https://www.cnblogs.com/FBsharl/p/18132959

相关文章

  • c++结构体、共用体(联合体)
    union数据成员共享同一段内存,在使用时按照最大成员变量的大小开辟空间,相对struct比较是节省内存的。内存空间是以占内存最大的以准。 struct数据成员各占一段内存,在使用时按照各自成员变量的大小开辟空间。 如图:一个学生(姓名namechar[10],年龄oldshort,电话telchar[......
  • 通过__cplusplus查看c++版本并检查gcc支持版本
    虽然平时开发都是用的c++11标准,但打算看一下wslubuntu里面的gcc默认支持什么标准~1打印__cplusplus宏#include<cstdio>intmain(){printf("%ld\n",__cplusplus);}➜testg++test_cpp_version.cpp-otest_cpp_version➜test./test_cpp_version20......
  • C++,四种强制类型转换,static_cast,const_cast,dynamic_cast,reinterpret_cast
      #include<iostream>usingnamespacestd;structA{virtualvoidfunc(){cout<<"Afunc"<<endl;}};structB:publicA{voidfunc(){cout<<"Bfunc"<<endl;}};intmain(){c......
  • C++未定义行为
    0前言未定义行为(UndefinedBehavior)是指语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另......
  • C++ Prime 学习
    C++利用using语句:其一:指定别名点击查看代码intp[4][4]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};for(int(*i)[4]=p;i!=p+4;i++){ for(int*j=*i;j!=*i+4;j++){ cout<<*j<<endl; }}利用using之后点击查看代码<summary>点击查看代码</su......
  • JS 原型链查找 (上)
    我们都知道面向对象语言如Java,C++等都基本实现了封装,继承,多态等特性,用面向对象语言来编程的基本套路就是抽象出类,然后实例化,用实例调用方法来模拟进行程序间的通信.但JS不是面向对象的语言,或者我们称它的脚本语言,它的一等公民就是对象/函数.本篇这里主......
  • C++ 解引用与函数基础:内存地址、调用方法及声明
    C++解引用获取内存地址和值在上一页的示例中,我们使用了指针变量来获取变量的内存地址(与引用运算符&一起使用)。但是,你也可以使用指针来获取变量的值,这可以通过使用*运算符(解引用运算符)来实现:stringfood="Pizza";//变量声明string*ptr=&food;//指针声明//引用......
  • C++算法题解 - 递归实现排列型枚举 - 递归法 (图文) (递归搜索树)
    题目:递归实现排列型枚举把1∼n这n个整数排成一行后随机打乱顺序,输出所有可能的次序。输入格式一个整数n。输出格式按照从小到大的顺序输出所有方案,每行1个。首先,同一行相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。数据......
  • 182 查找重复的电子邮箱
    182查找重复的电子邮箱表: Person+-------------+---------+|ColumnName|Type|+-------------+---------+|id|int||email|varchar|+-------------+---------+id是该表的主键(具有唯一值的列)。此表的每一行都包含一封电子邮件。电子......
  • C++,文件,文件夹操作,创建、删除、检测
     推荐 filesystem,特别好用,除了新建、删除、复制、移动文件夹,还支持磁盘空间检测,权限检测,路径处理。 一、使用系统库//检测文件,检测文件夹/*windows*头文件:io.h*函数:intaccess(constchar*_Filename,int_AccessMode);**_AccessMode参数说明:00表示只判断......