"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > 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 » ?

Publié le 2024-12-23
Parcourir:101

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 tentez d'utiliser l'idiome Eraser-remove_if pour éliminer des paires d'un std :: vector >, un problème particulier se pose. Malgré le ciblage des paires avec une valeur .first de 4 pour la suppression, l'implémentation initiale laisse derrière elle une paire en double :

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [&](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 des é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.
  • Vector Erasure: 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).

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3