370 votes

vérifier si un std::vector contient un certain objet ?

Y a-t-il quelque chose dans <algorithm> qui permet de vérifier si un conteneur std: : contient quelque chose ? Ou, un moyen d'en fabriquer un, par exemple :

if(a.x == b.x && a.y == b.y)
return true;

return false;

Cela ne peut se faire qu'avec std::map puisqu'il utilise des clés ?

Gracias

0 votes

S'il contient quelque chose de spécifique, ou simplement s'il n'est pas vide ?

2 votes

Quelle référence C++ utilisez-vous ? Et l'en-tête s'appelle <algorithm> - note no .h.

0 votes

Quelque chose de spécifique, comme une structure personnalisée.

699voto

You Points 8861

Vérifier si v contient l'élément x :

#include <algorithm>

if(std::find(v.begin(), v.end(), x) != v.end()) {
    /* v contains x */
} else {
    /* v does not contain x */
}

Vérifier si v contient des éléments (est non vide) :

if(!v.empty()){
    /* v is non-empty */
} else {
    /* v is empty */
}

33 votes

Que se passe-t-il si x est le dernier élément de v ?

125 votes

David, end() pointe sur un élément après le dernier, donc tout fonctionne.

4 votes

Cela tient-il compte de la tolérance numérique lorsqu'on essaie de déterminer si un double se trouve dans le vecteur ?

139voto

AshleysBrain Points 11439

Si la recherche d'un élément est importante, je recommande std::set au lieu de std::vector . En utilisant ceci :

std::find(vec.begin(), vec.end(), x) s'exécute en temps O(n), mais std::set a sa propre find() membre (c'est-à-dire myset.find(x) ) qui s'exécute en temps O(log n) - c'est beaucoup plus efficace avec un grand nombre d'éléments.

std::set garantit également que tous les éléments ajoutés sont uniques, ce qui vous évite de devoir faire quelque chose comme if not contained then push_back()... .

1 votes

Génial ! !! Je suis en train d'écrire un lexer. Les ensembles seront bien meilleurs que les vecteurs. Est-ce que set ont un count méthode comme map ? Je veux aussi pouvoir obtenir l'index de l'élément dans un ensemble.

4 votes

Excellente information ! Merci d'avoir à la fois répondu à la question directe et fourni une solution supplémentaire.

30 votes

C'est un mauvais conseil. Si les performances sont importantes, choisissez le profil. Il n'y a aucune garantie que l'analyse de la complexité ait quelque chose à dire sur votre problème spécifique.

15voto

NeilDurant Points 872

Voir question : Comment trouver un élément dans un std::vector ?

Vous devrez également vous assurer que vous avez mis en place un système de gestion de l'information approprié. operator==() pour votre objet, si celui par défaut n'est pas suffisant pour un test d'égalité "profond".

1 votes

Normalement, je n'implémenterais pas une operator==() pour que ma classe puisse juste utiliser std::find() une ou deux fois. Je ne le ferais que si cela a vraiment un sens d'ajouter cette surcharge à l'interface publique de votre classe. Le besoin d'être capable d'utiliser std::find() ne le justifie pas. De plus, que se passe-t-il si vous devez faire std::find() deux fois mais vous avez besoin de comparer vos objets d'une manière différente ? Par exemple, sur une autre propriété ?

0 votes

Si vous êtes soucieux de mettre en œuvre la operator== alors je recommande d'utiliser std::find_if vous pourriez alors avoir des prédicats réutilisables pour vos différents cas de critères.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X