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();
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();
_
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.
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;
}
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é.
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).
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 .
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.
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();
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).
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);
_
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()
}
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.
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);
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!");
}
}
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));
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;
}
(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.