IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

std::vector supprimer un ensemble d'�l�ments


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre chevronn� Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    D�tails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par d�faut std::vector supprimer un ensemble d'�l�ments
    Bonjour,

    Je cherche une m�thode efficace pour supprimer un ensemble d'�l�ments quelconques d'un std::vector. Je sais qu'il n'est pas conseill� de modifier un vector lorsqu'on le parcours avec une simple boucle incr�mentant un indice ou un it�rateurs (std::vector<T>::iterator).


    Alors, quelles seraient vos strat�gies ?

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    D�tails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par d�faut
    Bonjour,
    Globalement, tu as trois choix :

    1) Si ton ensemble d'�l�ment � effacer est en fait un intervalle contigu alors tu peux faire vector::erase(debutIntervalle, finIntervalle);

    2) Si chaque �l�ment de ton ensemble � effacer satisfait un certain crit�re alors tu peux faire un std::remove_if(critere) suivi de std::erase.

    3) Si aucun des deux pr�c�dents alors il faut se rabbatre sur une boucle avec un it�rateur et effacer les �l�ments de l'ensemble un par un, en suivant la m�thode de la faq pour ne pas s'emm�ler les pinceaux avec l'it�rateur courant.

  3. #3
    Membre chevronn� Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    D�tails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par d�faut
    Merci.

    Dans mon cas, j'ai deux std::vector. Un qui contient tous les �l�ments, et l'autre, les indices des �l�ments � effacer. Je ne vois pas d'autre solution que de copier tous les �l�ments � ne pas effacer dans un autre vector, comme cela :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    std::vector<Objet> elements; 
     
    // ...
     
    std::vector<size_t> a_effacer = selection();
     
    std::vector<Objet> elements_gardes;
     
    for(size_t i =0; i < elements.size(); ++i)
    {
       bool garder = true;
       for(size_t j =0; j < a_effacer.size(); ++j)
       {
            if( i == a_effacer[j])
            {
                garder = false;
                break;
            }
       }
     
       if(garder)
          element_gardes.push_back(elements[i]);
    }
    Mais je trouve �a un peu lourd, alors que mes �l�ments � effacer sont connus.

  4. #4
    R�dacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par d�faut
    Si l'ordre des �l�ments de ton vecteur n'a pas d'importance, tu peux faire comme suit :
    1/ trier le vecteur a_effacer ;
    2/ Parcourir ce tableau dans le sens inverse (par valeur d'index d�croissant) :
    2.1/ �changer l'�l�ment courant et le dernier ;
    2.2/ diminuer la taille du tableau de 1 ;

    Ce qui donnerait quelque chose comme �a :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    std::sort(a_effacer.begin(),a_effacer.end()); // a_efface[i]<a_effacer[j] <=> i<j
    std::vector<Objet>::size_type last_item = element.size()-1;
    for(
        std::vector<size_t>::const_reverse_iterator it = a_effacer.rbegin();
        it!=a_effacer.rend();
        ++it
    )
    {
        std::swap(element[*it],element[last_item]);
        --last_item;
    }
    element.resize(last_item+1);

Discussions similaires

  1. std vector erase sur un range d'�l�ments
    Par Muska17 dans le forum C++/CLI
    R�ponses: 2
    Dernier message: 08/09/2014, 11h04
  2. R�ponses: 8
    Dernier message: 26/02/2013, 18h17
  3. char[50] et std::vector<>
    Par tut dans le forum SL & STL
    R�ponses: 9
    Dernier message: 12/10/2004, 13h26
  4. R�ponses: 8
    Dernier message: 26/08/2004, 18h59
  5. Sauvegarde std::vector dans un .ini
    Par mick74 dans le forum MFC
    R�ponses: 2
    Dernier message: 12/05/2004, 13h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo