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

工作中经常遇见的一个场景:判断某个元素是否在vector容器中。

当然,会有很多种方法,由内置数据类型到自定义数据类型,下面简单总结一下。

【1】内置数据类型

代码胜过一切文档。如下示例代码:

  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 #include <algorithm>
  5 #include <set>
  6 
  7 // 为了便于示例,声明全局容器
  8 std::vector<std::string> strVec;
  9 
 10 void methods(const std::string& target)
 11 {
 12     // 方法一:遍历容器,查找相等元素判断是否存在
 13     {
 14         for (const auto& item : strVec)
 15         {
 16             if (item == target)
 17             {
 18                 std::cout << "method1: find " << target << " exists." << std::endl;
 19                 break;
 20             }
 21         }
 22     }
 23     // 方法二:获取元素个数,通过个数判断是否存在
 24     {
 25         int nCount = std::count(strVec.begin(), strVec.end(), target);
 26         if (nCount > 0)
 27         {
 28             std::cout << "method2: find " << target << " exists." << std::endl;
 29         }
 30     }
 31     // 方法三:查询元素迭代器,通过迭代器有效性判断是否存在
 32     {
 33         auto iter = std::find(strVec.begin(), strVec.end(), target);
 34         if (iter != strVec.end())
 35         {
 36             std::cout << "method3: find " << target << " exists." << std::endl;
 37         }
 38     }
 39     // 方法四:查询相等元素的迭代器,通过迭代器有效性判断是否存在
 40     {
 41         auto iter = std::find_if(strVec.begin(), strVec.end(), [&](const std::string& item)->bool
 42             { return (item == target); });
 43         if (iter != strVec.end())
 44         {
 45             std::cout << "method4: find " << target << " exists." << std::endl;
 46         }
 47     }
 48     // 方法五:利用std::any_of
 49     {
 50         if (std::any_of(strVec.begin(), strVec.end(), [&](const std::string& item) {
 51             return (item == target); }))
 52         {
 53             std::cout << "method5: find " << target << " exists." << std::endl;
 54         }
 55     }
 56     // 方法六:利用std::none_of
 57     {
 58         if (!std::none_of(strVec.begin(), strVec.end(), [&](const std::string& item) {
 59             return (item == target); }))
 60         {
 61             std::cout << "method6: find " << target << " exists." << std::endl;
 62         }
 63     }
 64     // 方法七:利用std::set唯一性
 65     {
 66         std::set<std::string> strSet;
 67         strSet.insert(strVec.begin(), strVec.end());
 68         if (!strSet.insert(target).second)
 69         {
 70             std::cout << "method7: find " << target << " exists." << std::endl;
 71         }
 72     }
 73 }
 74 
 75 int main()
 76 {
 77     strVec = { "C", "C++", "Java", "Python", "Lua", "Sql" };
 78     // 场景1:查找Ruby
 79     std::cout << "Find Ruby" << std::endl;
 80     methods("Ruby");
 81     // 场景2:查找C++
 82     std::cout << "Find C++" << std::endl;
 83     methods("C++");
 84 
 85     system("pause");
 86     return 0;
 87 }
 88 
 89 // result
 90 /*
 91 Find Ruby
 92 Find C++
 93 method1: find C++ exists.
 94 method2: find C++ exists.
 95 method3: find C++ exists.
 96 method4: find C++ exists.
 97 method5: find C++ exists.
 98 method6: find C++ exists.
 99 method7: find C++ exists.
100 */

【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.

顺序 选择 循环 总结

posted @ 2020-05-31 16:00  kaizenly  阅读(15517)  评论(0编辑  收藏  举报
打赏