8

Как узнать, присутствует ли элемент в std::vector?

1

У меня есть проблема: мне нужно проверить, существует ли элемент в векторе или нет, чтобы соответственно обработать каждый случай.

Вот что я пытаюсь сделать:

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

Как правильно проверить наличие элемента в векторе и использовать соответствующую логику в C++?

5 ответ(ов)

0

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

if(std::find(vector.begin(), vector.end(), item) != vector.end()){
    // Элемент найден
}

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

if(binary_search(vector.begin(), vector.end(), item)){
    // Элемент найден
}

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

0

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

#include <algorithm>
#include <vector>

using namespace std;

int main()
{   
    typedef vector<int> IntContainer;
    typedef IntContainer::iterator IntIterator;

    IntContainer vw;

    //...

    // Ищем число 5
    IntIterator i = find(vw.begin(), vw.end(), 5);

    if (i != vw.end()) {
        // найдено
    } else {
        // не существует
    }

    return 0;
}

В приведенном примере мы создаем контейнер vector<int>, и используем find для поиска числа 5 в этом векторе. Если элемент найден, итератор i будет указывать на его положение; если нет, i будет равен vw.end(). Обратите внимание, что для пользовательских типов данных необходимо обеспечить возможность сравнения по равенству.

0

Вам не обязательно использовать составные конструкции для проверки наличия элемента в векторе, так как это можно сделать более кратко. Однако, ваш подход с оберткой проверки в шаблонную функцию Contains действительно делает код более читаемым и удобным для повторного использования.

Ваш код выглядит следующим образом:

#include <algorithm>
#include <vector>

template <typename T> 
const bool Contains( std::vector<T>& Vec, const T& Element ) 
{
    return std::find(Vec.begin(), Vec.end(), Element) != Vec.end();
}

// Использование
if (Contains(vector, item))
    // действия, если элемент найден
    blah;
else
    // действия, если элемент не найден
    blah;

Такая функция делает код более понятным, так как явно показывает намерения. Не забывайте, что вы также можете использовать std::set или другие структуры данных, если вам нужно более эффективное решение для проверки принадлежности элемента. Но для простоты и удобочитаемости ваш метод вполне хорош, особенно если вектор не очень большой или если в вашем случае важна именно читаемость кода.

0

В C++20 с использованием диапазонов (#include <ranges>) вы можете проверить наличие элемента в векторе с помощью функции std::ranges::find. Вот пример кода, который иллюстрирует, как это можно сделать:

// ПРИМЕР ДАННЫХ
std::vector<int> vecOfElements = { 2, 4, 6, 8 };

// СДЕЛАТЬ ЧТО-ТО, ЕСЛИ 8 В ВЕКТОРЕ
if (std::ranges::find(vecOfElements, 8) != vecOfElements.end())
{
    std::cout << "СДЕЛАТЬ ЧТО-ТО" << std::endl;
}

В этом коде мы сначала создаем вектор vecOfElements с некоторыми элементами. Затем, используя std::ranges::find, мы ищем значение 8 в векторе. Если 8 найден, функция find возвращает итератор на этот элемент, и условие будет истинным, что приведет к выполнению блока кода внутри if. В результате будет выведено сообщение "СДЕЛАТЬ ЧТО-ТО".

0

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

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь