Si par exemple vous avez un std::vector<MyClass>
, où MyClass
a une méthode publique: bool isTiredOfLife()
, comment supprimez-vous les éléments qui retournent true?Comment supprimer les éléments d'un vecteur std :: basé sur une propriété des éléments?
Répondre
Je préfère remove_if
v.erase(remove_if(v.begin(), v.end(),
mem_fun_ref(&MyClass::isTiredOfLife)),
v.end());
remove_if
retourne un pointage iterator après le dernier élément qui est encore dans la séquence. erase
efface tout de son premier à son dernier argument (les deux itérateurs). L'utilisation de remove_if est la "bonne" façon de faire cela avec
Veillez à NE PAS utiliser un itérateur pour parcourir et effacer, car la suppression d'éléments invalide l'itérateur. En fait, tout exemple qui utilise erase() comme méthode principale est une mauvaise idée sur les vecteurs, car erase est O (n), ce qui rendra votre algorithme O (n^2). Cela devrait être un algorithme O (n).
La méthode que je donne ci-dessous est susceptible d'être plus rapide que remove_if mais, contrairement à remove_if, NE préservera PAS l'ordre relatif des éléments. Si vous souhaitez conserver l'ordre (c'est-à-dire que votre vecteur est trié), utilisez remove_if, comme dans la réponse ci-dessus. Si vous ne se soucient pas de l'ordre, et si le nombre d'éléments à supprimer est généralement moins d'un quart du vecteur, cette méthode est susceptible d'être plus rapide:
for(size_t i = 0; i < vec.size();)
if(vec[i].isTiredOfLife())
{
vec[i] = vec.back();
vec.pop_back();
}
else
++i;
D'oh. J'ai oublié cela. C'est même en gras dans la page que j'ai liée. : o J'ai supprimé mon post, donc personne ne l'utilise. – Bernard
Cela ne réorganisera-t-il pas les éléments du vecteur? En supposant que, par exemple, le vecteur d'entrée est trié, le vecteur de sortie ne le fera pas, le dernier élément prendra la position du premier élément supprimé. –
Vous voudrez peut-être mettre à jour votre réponse pour ne plus vous référer à Bernard. –
J'oublièrent remove_if() +1 . –
Très cool. Je n'ai jamais vu ça avant. +1 – Bernard
Merci, cela a fait l'affaire. –