std::vector 判斷vector容器中是否存在某元素


工作中經常遇見的一個場景:判斷某個元素是否在vector容器中。

當然,會有很多種方法,由內置數據類型到自定義數據類型,下面簡單總結一下。

【1】內置數據類型

代碼勝過一切文檔。如下示例代碼:

 1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 
 5 // 為了便於示例,聲明全局容器
 6 std::vector<std::string> strVec;
 7 
 8 void methods(const std::string& target)
 9 {
10     // 方法一:遍歷容器,查找相等元素判斷是否存在
11     {
12         for (const auto& item : strVec)
13         {
14             if (item == target)
15             {
16                 std::cout << "method1: find " << target << " exists." << std::endl;
17                 break;
18             }
19         }
20     }
21     // 方法二:獲取元素個數,通過個數判斷是否存在
22     {
23         int nCount = std::count(strVec.begin(), strVec.end(), target);
24         if (nCount > 0)
25         {
26             std::cout << "method2: find " << target << " exists." << std::endl;
27         }
28     }
29     // 方法三:查詢元素迭代器,通過迭代器有效性判斷是否存在
30     {
31         auto iter = std::find(strVec.begin(), strVec.end(), target);
32         if (iter != strVec.end())
33         {
34             std::cout << "method3: find " << target << " exists." << std::endl;
35         }
36     }
37     // 方法四:查詢相等元素的迭代器,通過迭代器有效性判斷是否存在
38     {
39         auto iter = std::find_if(strVec.begin(), strVec.end(), [&](const std::string& item)->bool
40             { return (item == target); });
41         if (iter != strVec.end())
42         {
43             std::cout << "method4: find " << target << " exists." << std::endl;
44         }
45     }
46 }
47 
48 int main()
49 {
50     strVec = { "C", "C++", "Java", "Python", "Lua", "Sql" };
51     // 場景1:查找Ruby
52     std::cout << "Find Ruby" << std::endl;
53     methods("Ruby");
54     // 場景2:查找C++
55     std::cout << "Find C++" << std::endl;
56     methods("C++");
57 
58     system("pause");
59     return 0;
60 }
61 
62 // result
63 /*
64 Find Ruby
65 Find C++
66 method1: find C++ exists.
67 method2: find C++ exists.
68 method3: find C++ exists.
69 method4: find C++ exists.
70 */

【2】自定義數據類型

代碼勝過一切文檔。如下示例代碼:

 1 #include <iostream>
 2 #include <map>
 3 #include <string>
 4 #include <vector>
 5 
 6 struct Student
 7 {
 8     std::string code;  // 學號(唯一性標識)
 9     int grade;         // 年級
10     std::map<std::string, double> scores; // <科目,成績>
11 
12     bool operator==(const Student& obj) const
13     {
14         return obj.code == code; // 只要學號相同即可
15     }
16 };
17 
18 // 為了便於示例,聲明全局容器
19 std::vector<Student> vecStu;
20 
21 void methods(const Student& target)
22 {
23     // 方法一:遍歷容器,查找相等元素判斷是否存在
24     {
25         for (const auto& item : vecStu)
26         {
27             if (item == target)
28             {
29                 std::cout << "method1: find exists." << std::endl;
30                 break;
31             }
32         }
33     }
34     // 方法二:獲取元素個數,通過個數判斷是否存在
35     {
36         int nCount = std::count(vecStu.begin(), vecStu.end(), target);
37         if (nCount > 0)
38         {
39             std::cout << "method2: find exists." << std::endl;
40         }
41     }
42     // 方法三:查詢元素迭代器,通過迭代器有效性判斷是否存在
43     {
44         auto iter = std::find(vecStu.begin(), vecStu.end(), target);
45         if (iter != vecStu.end())
46         {
47             std::cout << "method3: find exists." << std::endl;
48         }
49     }
50     // 方法四:查詢相等元素的迭代器,通過迭代器有效性判斷是否存在
51     {
52         if (std::find_if(vecStu.begin(), vecStu.end(), [&](const Student& obj)->bool
53             { return (obj == target); }) != vecStu.end())
54         {
55             std::cout << "method4: find exists." << std::endl;
56         }
57     }
58 }
59 
60 int main()
61 {
62     vecStu.push_back({ "080605109", 6, { {"English", 100}, {"China", 100} } });
63     vecStu.push_back({ "080605110", 7, { {"English", 99}, {"China", 70} } });
64     vecStu.push_back({ "080605111", 8, { {"English", 98}, {"China", 69} } });
65     vecStu.push_back({ "080605112", 6, { {"English", 97}, {"China", 68} } });
66     vecStu.push_back({ "080605113", 7, { {"English", 96}, {"China", 67} } });
67     Student obj = { "080605114", 8, { {"English", 95}, {"China", 66} } };
68     vecStu.push_back(obj);
69 
70     // 場景1:查找學號為[0806005109]的學生,我們暫不關注成績
71     std::cout << "Find code: 0806005108" << std::endl;
72     methods(Student{ "0806005108", {} });
73     // 場景2:查找學號為[0806005114]的學生,我們暫不關注成績
74     std::cout << "Find code: 0806005114" << std::endl;
75     methods(obj);
76     // 場景3:不想通過學號,只想查找六年級,是否存在英語和語文全為滿分的學生
77     auto iter = std::find_if(vecStu.begin(), vecStu.end(), [&](const Student& obj)->bool
78         { return (obj.grade == 6 && 
79             obj.scores.find("English")->second == 100 &&
80             obj.scores.find("China")->second == 100); });
81     if (iter != vecStu.end())
82     {
83         std::cout << "method: find 100 exists." << std::endl;
84     }
85 
86     return 0;
87 }
88 
89 // result
90 /*
91 Find code: 0806005108
92 Find code: 0806005114
93 method1: find exists.
94 method2: find exists.
95 method3: find exists.
96 method4: find exists.
97 method: find 100 exists.
98 */

注意:自定義數據類型,必須重載==符號。

原因很簡單:遇見這種場景,計算機弄不明白你想讓它以什么標准來判斷兩個對象相等,所以你得給它確定了相等的標准或准則。

綜上所述,再強調一點:針對自定義數據類型,使用std::find_if方法,顯而易見,自由度很大。

 

good good study, day day up.

順序 選擇 循環 總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM