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.

顺序 选择 循环 总结

原文地址:https://www.cnblogs.com/Braveliu/p/13019377.html