Все, что я хочу сделать, это проверить, существует ли элемент в векторе или нет, поэтому я могу иметь дело с каждым случаем.
if ( item_present )
do_this();
else
do_that();
Все, что я хочу сделать, это проверить, существует ли элемент в векторе или нет, поэтому я могу иметь дело с каждым случаем.
if ( item_present )
do_this();
else
do_that();
Вы можете использовать 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();
Как говорили другие, используйте STL find
или find_if
. Но если вы ищете очень большие векторы, и это влияет на производительность, вы можете отсортировать свой вектор, а затем использовать binary_search
, lower_bound
или upper_bound
.
Используйте find из заголовка алгоритма stl.I показало его использование с типом 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;
}
Если ваш вектор не упорядочен, используйте подход, предложенный 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 для сортировки вектора сначала, чтобы гарантировать его упорядочение.
Я использую что-то вроде этого...
#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
... таким образом он на самом деле понятен и читабель. (Очевидно, вы можете повторно использовать шаблон в нескольких местах).
Вот функция, которая будет работать для любого контейнера:
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
является зависимым именем.
Имейте в виду, что если вы собираетесь делать много поисков, есть контейнеры STL, которые лучше для этого. Я не знаю, что ваше приложение, но ассоциативные контейнеры, такие как std:: map, заслуживают рассмотрения.
std::vector - это контейнер выбора, если у вас нет причины для другого, и поиск по значению может быть такой причиной.
В С++ 11 вы можете использовать any_of
. Например, если это vector<string> v;
затем:
if (any_of(v.begin(), v.end(), bind(equal_to<string>(), item, _2)))
do_this();
else
do_that();
Используйте функцию STL find.
Имейте в виду, что существует функция find_if, которую вы можете использовать, если ваш поиск более сложный, не просто поиск элемента, но, например, хотите увидеть, есть ли элемент, который выполняет определенное условие, например строку, начинающуюся с "abc". (find_if
даст вам итератор, который указывает на первый такой элемент).
С boost вы можете использовать any_of_equal
:
#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);
Вы можете попробовать этот код:
#include <algorithm>
#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()
}
Вы можете использовать функцию find
, найденную в пространстве имен std
, то есть std::find
. Вы передаете функцию std::find
тетера begin
и end
из вектора, который хотите найти, вместе с элементом, который вы ищете, и сравните полученный итератор с концом вектора, чтобы увидеть, соответствуют ли они или нет.
std::find(vector.begin(), vector.end(), item) != vector.end()
Вы также можете разыменовать этот итератор и использовать его как обычно, как и любой другой итератор.
Вы также можете использовать счетчик. Он вернет количество элементов, присутствующих в векторе.
int t=count(vec.begin(),vec.end(),item);
Если вы хотите найти строку в векторе:
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));
Другой пример с использованием операторов С++.
#include <vector>
#include <algorithm>
#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!");
}
}
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;
}
(С++ 17 и выше):
можно использовать std::search
также
Это также полезно для поиска последовательности элементов.
#include <algorithm>
#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;
}
Также есть гибкость прохождения некоторых поисковых алгоритмов. Обратитесь сюда.
Используя Newton C++, это проще, самодокументировано и быстрее, чем с std :: find, потому что возвращает bool напрямую.
bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
Я думаю, что очевидно, что делают функции.
include <newton/algorithm/algorithm.hpp>
if ( newton::exists_linear(first, last, value) )
do_this();
else
do_that();