How to find out if an item is present in a std::vector?
我要做的就是检查向量中是否存在元素,这样我就可以处理每种情况。
1 2 3 4 | if ( item_present ) do_this(); else do_that(); |
您可以从
1 2 3 4 | #include <vector> vector<int> vec; //can have other data types instead of int but must same datatype as item std::find(vec.begin(), vec.end(), item) != vec.end() |
这将返回一个bool(
1 2 3 4 5 6 7 | #include #include <vector> if ( std::find(vec.begin(), vec.end(), item) != vec.end() ) do_this(); else do_that(); |
如其他人所说,使用stl
使用stl的算法头find。我已经说明了它与int类型的用法。您可以使用任何您喜欢的类型,只要您可以比较是否相等(如果您的自定义类需要的话,重载==)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include #include <vector> using namespace std; int main() { typedef vector<int> IntContainer; typedef IntContainer::iterator IntIterator; IntContainer vw; //... // find 5 IntIterator i = find(vw.begin(), vw.end(), 5); if (i != vw.end()) { // found it } else { // doesn't exist } return 0; } |
如果矢量没有排序,请使用msn建议的方法:
1 2 3 | if(std::find(vector.begin(), vector.end(), item)!=vector.end()){ // Found the item } |
如果您的向量是有序的,请使用二进制搜索方法brian neal建议:
1 2 3 | if(binary_search(vector.begin(), vector.end(), item)){ // Found the item } |
二进制搜索产生O(log n)最坏的性能,这比第一种方法更有效。为了使用二进制搜索,可以首先使用qsort对向量进行排序,以确保向量是有序的。
我用这种东西…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include template <typename T> const bool Contains( std::vector<T>& Vec, const T& Element ) { if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end()) return true; return false; } if (Contains(vector,item)) blah else blah |
…这样,它实际上清晰易读。(显然,您可以在多个地方重用模板)。
以下是一个适用于任何容器的函数:
1 2 3 4 5 | template <class Container> const bool contains(const Container& container, const typename Container::value_type& element) { return std::find(container.begin(), container.end(), element) != container.end(); } |
注意,您可以使用1个模板参数,因为您可以从容器中提取
在C++ 11中,可以使用EDCOX1×16。例如,如果它是一个
1 2 3 4 | if (any_of(v.begin(), v.end(), bind2nd(equal_to<string>(), item))) do_this(); else do_that(); |
记住,如果你要做大量的查找,有更好的STL容器。我不知道您的应用程序是什么,但是像std::map这样的关联容器可能值得考虑。
std::vector是可供选择的容器,除非您有其他原因,并且按值查找可能是这样的原因。
使用stl find函数。
请记住还有一个find_if函数,如果您的搜索更复杂,也就是说,如果您不只是在寻找一个元素,而是想知道是否有一个元素满足某个条件,例如,一个以"abc"开头的字符串,那么您可以使用该函数。(
有了Boost,您可以使用
1 2 3 | #include <boost/algorithm/cxx11/any_of.hpp> bool item_present = boost::algorithm::any_of_equal(vector, element); |
您可以尝试以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include #include <vector> // You can use class, struct or primitive data type for Item struct Item { //Some fields }; typedef std::vector<Item> ItemVector; typedef ItemVector::iterator ItemIterator; //... ItemVector vtItem; //... (init data for vtItem) Item itemToFind; //... ItemIterator itemItr; itemItr = std::find(vtItem.begin(), vtItem.end(), itemToFind); if (itemItr != vtItem.end()) { // Item found // doThis() } else { // Item not found // doThat() } |
你也可以用计数。它将返回向量中存在的项数。
1 | int t=count(vec.begin(),vec.end(),item); |
可以使用
1 | std::find(vector.begin(), vector.end(), item) != vector.end() |
您还可以取消对该迭代器的引用,并像其他迭代器一样正常使用它。
如果要在向量中查找字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | struct isEqual { isEqual(const std::string& s): m_s(s) {} bool operator()(OIDV* l) { return l->oid == m_s; } std::string m_s; }; struct OIDV { string oid; //else }; VecOidv::iterator itFind=find_if(vecOidv.begin(),vecOidv.end(),isEqual(szTmp)); |
另一个示例使用C++运算符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <vector> #include #include <stdexcept> template<typename T> inline static bool operator ==(const std::vector<T>& v, const T& elem) { return (std::find(v.begin(), v.end(), elem) != v.end()); } template<typename T> inline static bool operator !=(const std::vector<T>& v, const T& elem) { return (std::find(v.begin(), v.end(), elem) == v.end()); } enum CODEC_ID { CODEC_ID_AAC, CODEC_ID_AC3, CODEC_ID_H262, CODEC_ID_H263, CODEC_ID_H264, CODEC_ID_H265, CODEC_ID_MAX }; void main() { CODEC_ID codec = CODEC_ID_H264; std::vector<CODEC_ID> codec_list; codec_list.reserve(CODEC_ID_MAX); codec_list.push_back(CODEC_ID_AAC); codec_list.push_back(CODEC_ID_AC3); codec_list.push_back(CODEC_ID_H262); codec_list.push_back(CODEC_ID_H263); codec_list.push_back(CODEC_ID_H264); codec_list.push_back(CODEC_ID_H265); if (codec_list != codec) { throw std::runtime_error("codec not found!"); } if (codec_list == codec) { throw std::logic_error("codec has been found!"); } } |
1 2 3 4 5 6 | template <typename T> bool IsInVector(T what, std::vector<T> * vec) { if(std::find(vec->begin(),vec->end(),what)!=vec->end()) return true; return false; } |
(C++ 17及以上):
也可以使用
这对于搜索元素序列也很有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include #include <iostream> #include <vector> template <typename Container> bool search_vector(const Container& vec, const Container& searchvec) { return std::search(vec.begin(), vec.end(), searchvec.begin(), searchvec.end()) != vec.end(); } int main() { std::vector<int> v = {2,4,6,8}; //THIS WORKS. SEARCHING ONLY ONE ELEMENT. std::vector<int> searchVector1 = {2}; if(search_vector(v,searchVector1)) std::cout<<"searchVector1 found"<<std::endl; else std::cout<<"searchVector1 not found"<<std::endl; //THIS WORKS, AS THE ELEMENTS ARE SEQUENTIAL. std::vector<int> searchVector2 = {6,8}; if(search_vector(v,searchVector2)) std::cout<<"searchVector2 found"<<std::endl; else std::cout<<"searchVector2 not found"<<std::endl; //THIS WILL NOT WORK, AS THE ELEMENTS ARE NOT SEQUENTIAL. std::vector<int> searchVector3 = {8,6}; if(search_vector(v,searchVector3)) std::cout<<"searchVector3 found"<<std::endl; else std::cout<<"searchVector3 not found"<<std::endl; } |
此外,还可以灵活地传递一些搜索算法。请参考这里。
https://en.cppreference.com/w/cpp/algorithm/search/搜索
使用牛顿C++,它比STD更容易、自文档化和更快:因为直接返回BoOL而找到。
1 2 3 | bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value ) bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value ) |
我认为很明显这些函数是做什么的。
1 2 3 4 5 6 | include <newton/algorithm/algorithm.hpp> if ( newton::exists_linear(first, last, value) ) do_this(); else do_that(); |