Supprimer doublons dans un vector

Supprimer doublons dans un vector - C++ - Programmation

Marsh Posté le 18-04-2011 à 14:52:11    

bonjour, voici le problème auquel je suis confronté.
 
J'ai une classe Coordonnée :

Code :
  1. class Coordonees
  2. {
  3.     private:
  4.         int x;
  5.         int y;
  6. };


 
dans une méthode d'une autre classe, j'ai un vector de coordonnée contenant des doubles (double au sens : même couple de X et Y). Je souhaite donc les supprimer.
 
Mon code :
 

Code :
  1. for(int a = 0; a < retour.size() ; a++){
  2.       for(int b = a+1; b < retour.size() ; b++){
  3.            if((retour[a].getX()) == (retour[b].getX()) && ((retour[a].getY()) == (retour[b].getY()))) {
  4.                  retour.erase(retour.begin() + b);
  5.           }
  6.       }
  7. }


retour étant le vector.
 
Si je n'utilise pas ce code, le vector contient une vingtaine de Coordonnée, alors qu'avec le code il n'y en a plus que 8 que voici. Malheureusement comme on peut le constater, des doubles persistent (ici il y a trois fois le couple 6 et 6).
 
http://nsa25.casimages.com/img/2011/04/18/110418025523381246.png
 
si vous pouviez m'aider, merci.

Reply

Marsh Posté le 18-04-2011 à 14:52:11   

Reply

Marsh Posté le 18-04-2011 à 16:00:28    

Lorsque tu supprimes l'élément à la position b (ligne 4), l'élément suivant vient occuper la position b. Or, tu es en fin de boucle, donc b est incrémenté et tu perds un élément potentiellement en doublon.
 
A mon avis, tu devrais :
- changer tes boucles 'for' en boucles 'while', pour gérer toi-même l'incrémentation des éléments que tu parcours
- utiliser des itérateurs (la fonction erase retourne un itérateur sur l'élément suivant celui qui a été supprimé).
 
Ainsi, tu n'incrémentes ton itérateur que s'il n'a pas été supprimé.

Reply

Marsh Posté le 18-04-2011 à 18:28:18    

Si l'ordre de tes points n'est pas important, tu peux trier avec std::sort puis utiliser std::unique qui supprime les éléments consécutifs identiques.
Ces deux fonctions sont définies dans <algorithm>

Reply

Marsh Posté le 30-04-2011 à 16:46:56    

Pourquoi ne pas remplacer ton vector par un set ?  :o

Reply

Marsh Posté le 30-04-2011 à 20:31:49    

l'idiome correct est de faire un remove_if suivi d'un erase.
 
http://en.wikipedia.org/wiki/Erase-remove_idiom

Reply

Marsh Posté le 30-04-2011 à 22:58:09    

http://www.cplusplus.com/reference/algorithm/
 
sort (myvector.begin(), myvector.end(), taFonctionDeTri);
 
suivi de
 
unique (myvector.begin(), myvector.end(), taFonctionDeComparaison);
 
Ce n'est pas optimal mais ça fait le job.

Reply

Marsh Posté le 02-05-2011 à 13:47:29    

Il faut filler le resultat de unique a erase ou tu va avoir un probleme: quand on n'a que des iterateurs en arguments, enlever des elements au conteneur est difficile...


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed