10
votes

Comment supprimer tous les entiers égaux de Set en C ++

Je suis nouveau à C ++. J'aimerais savoir à quel point les codeurs expérimentés font cela.

Ce que j'ai: xxx

et bien sûr, cela ne fonctionne pas. parce que ITR est incrémenté après que cela soit effacé. Cela signifie-t-il que ITR doit indiquer au début de l'ensemble à chaque fois que je effacerai l'élément de l'ensemble?


0 commentaires

4 Réponses :


11
votes

Effacement d'un élément de STD :: Set Invalide uniquement Invalide Itérateurs pointant vers cet élément.

Obtenez un itérateur à l'élément suivant avant d'effacer l'élément cible.


0 commentaires

8
votes

Vous n'avez pas besoin de revenir au début. Set :: Effacement code> Invalide uniquement les itérateurs faisant état de l'élément étant effacé. Vous devez donc simplement avoir besoin de copier l'itérateur et d'incrémenter avant d'effacer:

for(set<int>::iterator itr = s.begin(); itr != s.end();)
{
    set<int>::iterator here = itr++;
    if (!(*here % 2))
        s.erase(here);
}


2 commentaires

Ok, j'abandonne. Quel est le bug?


J'avais tort, je pensais que tu sautais le premier élément. Je reprends mon commentaire et mon bowvote.



16
votes
 for(set<int>::iterator itr = s.begin(); itr != s.end(); ){
  if (!(*itr % 2))
      s.erase(itr++);

  else ++itr;
 }
effective STL by Scott Myers

2 commentaires

Pourquoi ITR ++ est-il autorisé dans la fonction effaçable, mais pas à l'extérieur?


ITR ++ est autorisé à l'extérieur, mais ++ IT est généralement préférable lorsque la valeur est inutilisée, pour des raisons pour des raisons d'avoir fastidieux d'entrer dans chaque fois que tout le monde le fait ;-) Dans ce cas, il pourrait être préférable d'ignorer la bonne pratique habituelle et d'écrire itr ++ , juste parce que le code lit légèrement plus lisse si c'est la même chose dans les deux cas.



-1
votes

Le meilleur moyen est d'utiliser la combinaison de remove_if et d'effacement

s.erase(remove_if(s.begin(), s.end(), evenOddFunctor), s.end())


3 commentaires

supprimer_if nécessite que opérateur * renvoie une lvalue non constituée. STD :: Ensemble impose qu'il est toujours commandé; Renvoyer un non-const lvalue de std :: Set :: opérateur * briserait cette garantie. Par conséquent, std :: remove_if () ne prend pas std :: set :: itérateur s


C'était réellement utile. J'ai été coincé à essayer de le faire avec Supprimer_if et cela m'a dit ce que le problème était. Merci.


@Ademiller moi aussi. Je déteste supprimer_if .