Как узнать, присутствует ли элемент в std :: vector? - PullRequest
563 голосов
/ 21 февраля 2009

Все, что я хочу сделать, это проверить, существует ли элемент в векторе или нет, чтобы я мог разобраться с каждым случаем.

if ( item_present )
   do_this();
else
   do_that();

Ответы [ 18 ]

840 голосов
/ 21 февраля 2009

Вы можете использовать std::find из <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()

Возвращает bool (true, если присутствует, false в противном случае). С вашим примером:

#include <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();
104 голосов
/ 21 февраля 2009

Как уже говорили другие, используйте функции STL find или find_if. Но если вы ищете в очень больших векторах, и это влияет на производительность, вы можете отсортировать ваш вектор и затем использовать binary_search, lower_bound или upper_bound алгоритмы.

46 голосов
/ 21 февраля 2009

Используйте find из заголовка алгоритма stl. Я проиллюстрировал его использование с типом int. Вы можете использовать любой понравившийся вам тип при условии, что вы можете сравнить на равенство (перегрузка ==, если вам нужно для своего пользовательского класса).

#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;
}
36 голосов
/ 23 ноября 2012

Если ваш вектор не упорядочен, используйте предложенный MSN подход:

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

Если ваш вектор упорядочен, используйте метод binary_search, предложенный Брайаном Нилом:

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

бинарный поиск дает O (log n) производительности в худшем случае, что намного эффективнее, чем при первом подходе. Чтобы использовать двоичный поиск, вы можете сначала использовать qsort для сортировки вектора, чтобы гарантировать, что он упорядочен.

20 голосов
/ 04 сентября 2013

Я использую что-то вроде этого ...

#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

... так как это на самом деле ясно и читаемо. (Очевидно, вы можете повторно использовать шаблон в нескольких местах).

11 голосов
/ 12 февраля 2016

Вот функция, которая будет работать для любого контейнера:

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 является зависимым именем .

10 голосов
/ 11 августа 2015

В C ++ 11 вы можете использовать any_of. Например, если это vector<string> v;, тогда:

if (any_of(v.begin(), v.end(), bind2nd(equal_to<string>(), item)))
   do_this();
else
   do_that();
10 голосов
/ 21 февраля 2009

Имейте в виду, что, если вы собираетесь делать много поисков, есть контейнеры STL, которые лучше подходят для этого. Я не знаю, какое у вас приложение, но стоит рассмотреть такие ассоциативные контейнеры, как std :: map.

std :: vector - контейнер выбора, если у вас нет причины для другого, и поиск по значению может быть такой причиной.

8 голосов
/ 21 февраля 2009

Используйте функцию STL find .

Имейте в виду, что есть также функция find_if , которую вы можете использовать, если ваш поиск более сложный, например, если вы ищете не просто элемент, а, например, хотите посмотреть если есть элемент, который удовлетворяет определенному условию, например, строка, начинающаяся с «abc». (find_if даст вам итератор, который указывает на первый такой элемент).

7 голосов
/ 27 сентября 2016

С бустом вы можете использовать any_of_equal:

#include <boost/algorithm/cxx11/any_of.hpp>

bool item_present = boost::algorithm::any_of_equal(vector, element);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...