关于C++:如何确定std :: vector中是否存在某个项?

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();


您可以从使用std::find

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(true,如果存在,则返回false,否则返回)。举个例子:

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 findfind_if函数。但是,如果搜索的向量非常大,这会影响性能,您可能需要对向量进行排序,然后使用binary_searchlower_boundupper_bound算法。


使用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个模板参数,因为您可以从容器中提取value_type。您需要typename,因为Container::value_type是从属名称。


在C++ 11中,可以使用EDCOX1×16。例如,如果它是一个vector v;,那么:

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"开头的字符串,那么您可以使用该函数。(find_if会给您一个指向第一个此类元素的迭代器)。


有了Boost,您可以使用any_of_equal

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);


可以使用find函数,该函数位于std命名空间中,即std::find。从要搜索的向量中传递std::find函数beginend迭代器,以及要查找的元素,并将结果迭代器与向量的末尾进行比较,以查看它们是否匹配。

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及以上):

也可以使用std::search

这对于搜索元素序列也很有用。

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();