Maison  >  Article  >  développement back-end  >  Pourquoi effacer-remove_if laisse-t-il des paires en double lors de la suppression d'éléments d'un « std :: vector » ?

Pourquoi effacer-remove_if laisse-t-il des paires en double lors de la suppression d'éléments d'un « std :: vector » ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-11 20:30:03271parcourir

Why does erase-remove_if leave behind duplicate pairs when removing elements from a `std::vector`?

Erase-Remove_if Idiom pour la suppression de paires

Lorsque vous essayez d'utiliser l'idiome Erase-remove_if pour éliminer des paires d'un std::vector< std::pair>, un problème particulier se pose. Malgré le ciblage des paires avec une valeur .first de 4 pour la suppression, la mise en œuvre initiale laisse derrière elle une paire en double :

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [&amp;](const stopPointPair stopPoint)-> bool { return stopPoint.first == 4; }));

La racine du problème réside dans le processus d'effacement incomplet. std::erase_if déplace uniquement les éléments correspondants vers la fin du vecteur ; cela ne les supprime pas. Pour terminer la suppression, l'approche correcte consiste à utiliser l'itérateur renvoyé par std::remove_if comme point de départ de l'effacement :

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [](const stopPointPair stopPoint)-> bool 
                                       { return stopPoint.first == 4; }), 
                 stopPoints.end());

Comprendre le mécanisme Erase-Remove_if :

  • Échange d'éléments : std::remove_if échange les éléments dans le vecteur, poussant tous les éléments incompatibles vers le début. Les éléments correspondants se retrouvent à l'arrière du vecteur.
  • Itération du prédicat : L'expression lambda du prédicat détermine les éléments à supprimer. Si le prédicat renvoie vrai, l'élément correspondant est déplacé vers la fin du vecteur.
  • Récupération d'itérateur : std::remove_if renvoie un itérateur pointant vers le premier élément correspondant au prédicat ; cet itérateur marque le début des éléments à supprimer.
  • Erasure du vecteur : std::vector::erase invoque l'opération d'effacement de plage, en commençant par l'itérateur renvoyé et en s'étendant jusqu'au vecteur fin. Cette étape supprime tous les éléments correspondants du vecteur.

Pour plus d'informations, reportez-vous à l'article Wikipédia sur [Erase-Remove Idiom](https://en.wikipedia.org/ wiki/Erase-remove_idiom).

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn