Como descobrir se um item está presente em um std::vector?

tudo o que eu quero fazer é verificar se um elemento existe no vector ou não, para que eu possa lidar com cada caso.

if ( item_present )
   do_this();
else
   do_that();
 649
Author: Antonio, 2009-02-20

18 answers

Pode usar std::find de <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()

Isto devolve um bool (true Se estiver presente, false caso contrário). Com o seu exemplo:

#include <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();
 968
Author: MSN, 2019-04-04 10:57:12

Como outros já disseram, use o STL find ou find_if funções. Mas se você procura muito grande de vetores e isso afeta o desempenho, poderá ordenar o seu vetor e, em seguida, usar o binary_search, lower_bound, ou upper_bound algoritmos.

 116
Author: Brian Neal, 2012-10-20 19:27:12

Usar O find a partir do cabeçalho do algoritmo de stl.Ilustrei o seu uso com o tipo int. Você pode usar qualquer tipo que você gosta, desde que você possa comparar para a igualdade (sobrecarga == se você precisar para a sua classe personalizada).

#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;
}
 51
Author: m-sharp, 2017-04-29 14:37:03

Se o seu vector não for ordenado, use a abordagem MSN sugerida:

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

Se o seu vector for ordenado, use o método binary_search Brian Neal sugerido:

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

A busca binária produz um desempenho de O (log n) no pior caso, o que é muito mais eficiente do que a primeira abordagem. A fim de usar a pesquisa binária, você pode usar o qsort para classificar o vetor primeiro para garantir que ele é ordenado.

 44
Author: spiralmoon, 2016-07-09 12:07:38
Eu uso algo assim...
#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
Assim é claro e legível. (Obviamente você pode reutilizar o modelo em vários lugares).
 23
Author: Andy Krouwel, 2014-01-09 23:11:10

Em C++11 pode usar any_of. Por exemplo, se for um vector<string> v; Então:

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

Em alternativa, utilize um lambda:

if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
   do_this();
else
   do_that();
 16
Author: Deqing, 2020-02-01 14:47:00
Aqui está uma função que funcionará para qualquer recipiente:
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();
}

Lembre-se que pode escapar com o parâmetro 1 modelo porque pode extrair o value_type do contentor. Você precisa do typename Porque Container::value_type é um Nome dependente .

 13
Author: Martin Broadhurst, 2018-02-28 20:56:22
Tenha em mente que, se você vai fazer um monte de pesquisas, existem recipientes STL que são melhores para isso. Eu não sei qual é a sua aplicação, mas containers associativos como std::map pode valer a pena considerar.

Std:: vector é o recipiente de escolha, a menos que tenha uma razão para outro, e as pesquisas pelo valor podem ser essa razão.

 10
Author: David Thornley, 2009-02-20 22:42:36

Utilize a função STL find.

, tenha em mente que há também um find_if função, que você pode usar se a pesquisa é mais complexo, i.e. se você não está apenas procurando por um elemento, mas, por exemplo, quer ver se há um elemento que cumpre uma determinada condição, por exemplo, uma seqüência de caracteres que começa com "abc". ({[[0]} dar-lhe-ia um iterador que apontasse para o primeiro desses elementos).

 8
Author: Frank, 2009-02-20 22:18:34

Com impulso pode usar any_of_equal:

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

bool item_present = boost::algorithm::any_of_equal(vector, element);
 8
Author: Mikhail, 2016-09-27 16:02:37

Pode tentar este código:

#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()
}
 5
Author: TrungTN, 2012-04-28 15:29:48

Podes usar o find função, encontrada no espaço de nomes std, ie std::find. Você passa a função std::find a begin e end iterador do vector que deseja procurar, juntamente com o elemento que procura e compara o iterador resultante com o fim do vector para ver se correspondem ou não.

std::find(vector.begin(), vector.end(), item) != vector.end()
Também és capaz de dereferenciar esse iterador e usá-lo como normal, como qualquer outro iterador.
 4
Author: TankorSmash, 2014-06-15 00:36:20

Também podes usar a contagem. Ele retornará o número de itens presentes em um vetor.

int t=count(vec.begin(),vec.end(),item);
 4
Author: Aditya, 2015-04-17 06:18:37

Se quiseres encontrar uma corda num vector:

    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));
 2
Author: Gank, 2013-05-31 13:55:53

(C++17 e superior):

Também

Isto também é útil para pesquisar sequência de elementos.

#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;
}

Também há flexibilidade de passar alguns algoritmos de busca. Veja aqui.

Https://en.cppreference.com/w/cpp/algorithm/search

 2
Author: Pavan Chandaka, 2019-03-26 19:23:26
template <typename T> bool IsInVector(const T & what, const std::vector<T> & vec)
{
    return std::find(vec.begin(),vec.end(),what)!=vec.end();
}
 2
Author: user3157855, 2020-07-03 08:23:17

Eu usei pessoalmente modelos de tarde para lidar com vários tipos de contentores ao mesmo tempo, em vez de lidar apenas com Vectores. Encontrei um exemplo similar online (não me lembro de onde), então o crédito vai para quem eu roubou isso. Este padrão em particular parece lidar com arrays raw também.

template <typename Container, typename T = typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type>
bool contains(Container && c, T v)
{
    return std::find(std::begin(c), std::end(c), v) != std::end(c);
}
 1
Author: Pascal Laferrière, 2019-10-28 15:41:58

Usando Newton C++ é mais fácil, auto-documentado e mais rápido do que com std::encontrar por causa do retorno de um bool directamente.

bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )

bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
Acho que é óbvio o que as funções fazem.
include <newton/algorithm/algorithm.hpp>

if ( newton::exists_linear(first, last, value) )
   do_this();
else
   do_that();
 -5
Author: Moises Rojo, 2018-04-11 12:10:35