Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out if an item is present in a std::vector?

Tags:

c++

std

vector

All I want to do is to check whether an element exists in the vector or not, so I can deal with each case.

if ( item_present )
   do_this();
else
   do_that();
like image 547
Joan Venge Avatar asked Feb 20 '09 21:02

Joan Venge


People also ask

How do you check if an item exists in a vector?

So, to check if an element exist in vector or not, we can pass the start & end iterators of vector as initial two arguments and as the third argument pass the value that we need to check. If element exists in the vector, then it will return the iterator pointing to that element.

How do you know if a std::vector is empty?

empty() returns true if the vector is empty, or false if the vector is not empty.


7 Answers

You can use std::find from <algorithm>:

#include <algorithm> #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() 

This returns an iterator to the first element found. If not present, it returns an iterator to one-past-the-end. With your example:

#include <algorithm> #include <vector>  if ( std::find(vec.begin(), vec.end(), item) != vec.end() )    do_this(); else    do_that(); 
like image 119
MSN Avatar answered Oct 06 '22 09:10

MSN


As others have said, use the STL find or find_if functions. But if you are searching in very large vectors and this impacts performance, you may want to sort your vector and then use the binary_search, lower_bound, or upper_bound algorithms.

like image 28
Brian Neal Avatar answered Oct 06 '22 10:10

Brian Neal


If your vector is not ordered, use the approach MSN suggested:

if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
      // Found the item
}

If your vector is ordered, use binary_search method Brian Neal suggested:

if(binary_search(vector.begin(), vector.end(), item)){
     // Found the item
}

binary search yields O(log n) worst-case performance, which is way more efficient than the first approach. In order to use binary search, you may use qsort to sort the vector first to guarantee it is ordered.

like image 23
spiralmoon Avatar answered Oct 06 '22 09:10

spiralmoon


Use find from the algorithm header of stl.I've illustrated its use with int type. You can use any type you like as long as you can compare for equality (overload == if you need to for your custom class).

#include <algorithm>
#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;
}
like image 27
m-sharp Avatar answered Oct 06 '22 09:10

m-sharp


In C++11 you can use any_of. For example if it is a vector<string> v; then:

if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
   do_this();
else
   do_that();

Alternatively, use a lambda:

if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
   do_this();
else
   do_that();
like image 20
Deqing Avatar answered Oct 06 '22 09:10

Deqing


I use something like this...

#include <algorithm>


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

...as that way it's actually clear and readable. (Obviously you can reuse the template in multiple places).

like image 20
Andy Krouwel Avatar answered Oct 06 '22 08:10

Andy Krouwel


Here's a function that will work for any Container:

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

Note that you can get away with 1 template parameter because you can extract the value_type from the Container. You need the typename because Container::value_type is a dependent name.

like image 35
Martin Broadhurst Avatar answered Oct 06 '22 10:10

Martin Broadhurst