Maison > développement back-end > C++ > 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
Libérer: 2024-11-11 20:30:03
original
375 Les gens l'ont consulté

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; }));
Copier après la connexion

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());
Copier après la connexion

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 de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal