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