Как узнать, присутствует ли элемент в std::vector?
У меня есть проблема: мне нужно проверить, существует ли элемент в векторе или нет, чтобы соответственно обработать каждый случай.
Вот что я пытаюсь сделать:
if ( item_present )
do_this();
else
do_that();
Как правильно проверить наличие элемента в векторе и использовать соответствующую логику в C++?
5 ответ(ов)
Если ваш вектор не отсортирован, используйте подход, предложенный 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
, чтобы гарантировать, что он отсортирован.
Вы можете использовать функцию 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()
. Обратите внимание, что для пользовательских типов данных необходимо обеспечить возможность сравнения по равенству.
Вам не обязательно использовать составные конструкции для проверки наличия элемента в векторе, так как это можно сделать более кратко. Однако, ваш подход с оберткой проверки в шаблонную функцию 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
или другие структуры данных, если вам нужно более эффективное решение для проверки принадлежности элемента. Но для простоты и удобочитаемости ваш метод вполне хорош, особенно если вектор не очень большой или если в вашем случае важна именно читаемость кода.
В 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
. В результате будет выведено сообщение "СДЕЛАТЬ ЧТО-ТО".
Имейте в виду, что если вы планируете выполнять много операций поиска, существуют контейнеры STL, которые лучше подходят для этой задачи. Я не знаю, какая у вас конкретная задача, но ассоциативные контейнеры, такие как std::map, могут быть достойным вариантом.
std::vector является предпочтительным контейнером, если у вас нет особой причины использовать другой, и поиск по значению может быть такой причиной.
В чем проблема с "using namespace std;"?
Как преобразовать экземпляр std::string в нижний регистр
Как удалить элемент из std::vector<> по индексу?
Как проверить, существует ли заданный ключ в std::map?
Что такое Правило трёх?