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.
顺序 选择 循环 总结