c++中的查詢list元素

FBshark發表於2024-04-13

回顧學習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

相關文章