web-dev-qa-db-fra.com

Comment savoir si un élément est présent dans un std :: vector?

Tout ce que je veux faire est de vérifier si un élément existe dans le vecteur ou non, afin de pouvoir traiter chaque cas.

if ( item_present )
   do_this();
else
   do_that();
574
Joan Venge

Vous pouvez utiliser std::find à partir 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()
_

Ceci retourne un booléen (true si présent, false sinon). Avec votre exemple:

_#include <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();
_
854
MSN

Comme d'autres l'ont dit, utilisez les fonctions STL find ou find_if . Toutefois, si vous effectuez une recherche dans de très grands vecteurs et que cela influe sur les performances, vous souhaiterez peut-être trier votre vecteur, puis utiliser le signe binary_search , lower_bound , ou upper_bound algorithmes.

106
Brian Neal

Utilisez find depuis l'en-tête de l'algorithme de stl.J'ai illustré son utilisation avec int type. Vous pouvez utiliser n'importe quel type tant que vous pouvez comparer pour l'égalité (surcharge == si vous en avez besoin pour votre classe personnalisée).

#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;
}
46
m-sharp

Si votre vecteur n'est pas commandé, utilisez l'approche suggérée par MSN:

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

Si votre vecteur est commandé, utilisez la méthode binary_search suggérée par Brian Neal:

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

la recherche binaire donne des performances dans le pire des cas (log n), ce qui est bien plus efficace que la première approche. Pour utiliser la recherche binaire, vous pouvez utiliser qsort pour trier d'abord le vecteur afin de garantir qu'il est ordonné.

37
Bin Feng

J'utilise quelque chose comme ça ...

#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

... de cette façon, il est en fait clair et lisible. (Évidemment, vous pouvez réutiliser le modèle à plusieurs endroits).

21
Andy Krouwel

Voici une fonction qui fonctionnera pour n'importe quel conteneur:

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();
}

Notez que vous pouvez vous en sortir avec 1 paramètre de modèle car vous pouvez extraire le value_type du conteneur. Vous avez besoin de typename car Container::value_type est un nom dépendant .

11
Martin Broadhurst

N'oubliez pas que si vous effectuez beaucoup de recherches, il existe des conteneurs STL qui conviennent mieux à cela. Je ne sais pas quelle est votre application, mais des conteneurs associatifs tels que std :: map peuvent être utiles.

std :: vector est le conteneur de choix à moins que vous n'ayez une raison pour une autre, et les recherches par valeur peuvent être une telle raison.

10
David Thornley

En C++ 11, vous pouvez utiliser any_of. Par exemple, s'il s'agit d'un vector<string> v;, alors:

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

Utilisez la fonction STL find .

N'oubliez pas qu'il existe également une fonction find_if , que vous pouvez utiliser si votre recherche est plus complexe, c'est-à-dire si vous ne recherchez pas simplement un élément, mais souhaitez par exemple voir s'il y en a une. est un élément qui remplit une certaine condition, par exemple une chaîne commençant par "abc". (find_if vous donnerait un itérateur qui pointe vers le premier élément de ce type).

8
Frank

Avec boost, vous pouvez utiliser any_of_equal :

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

bool item_present = boost::algorithm::any_of_equal(vector, element);
_
7
Mikhail

Vous pouvez essayer ce code:

#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
TrungTN

Vous pouvez utiliser la fonction find , située dans l'espace de noms std, c'est-à-dire std::find. Vous transmettez à la fonction std::find l'itérateur begin et end du vecteur que vous souhaitez rechercher, ainsi que l'élément que vous recherchez et vous comparez l'itérateur obtenu à la fin du vecteur pour voir s'ils correspondent ou non.

std::find(vector.begin(), vector.end(), item) != vector.end()

Vous pouvez également déréférencer cet itérateur et l'utiliser normalement, comme tout autre itérateur.

3
TankorSmash

Vous pouvez utiliser le compte aussi. Il renverra le nombre d'éléments présents dans un vecteur.

int t=count(vec.begin(),vec.end(),item);
3
Aditya

Un autre exemple utilisant des opérateurs C++.

#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!");
  }
}
2

Si vous voulez trouver une chaîne dans un vecteur:

    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
Gank
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;
}
1
user3157855

(C++ 17 et plus):

peut aussi utiliser std::search

Ceci est également utile pour rechercher une séquence d'éléments.

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

De plus, il est possible de passer des algorithmes de recherche en souplesse. Reportez-vous ici.

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

0
Pavan Chandaka