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 :

Déplacement d'éléments d'une "list"


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut Déplacement d'éléments d'une "list"
    Bonjour à tous,

    J'utilise des std::list pour stocker des éléments dont l'ordre est important (chaque élément est unique).
    J'ai besoin de déplacer certains éléments pour les mettre en fin de liste. La seule solution que j'aie trouvée pour l'instant, c'est de rechercher l'élément à déplacer, le supprimer, puis l'ajouter en fin de liste.

    Exemple de fonction qui le fait (si l'élément à déplacer n'existe pas, on se contente de l'ajouter) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void pushFront(Objet * MonObjet)
    {
        std::list<Objet *>::iterator i = find(ObjetList.begin(), ObjetList.end(), MonObjet);
     
        if (i != ObjetList.end())
        {
            ObjetList.erase(i);
        }
     
        ObjetList.push_back(MonObjet);
    }
    Existerait-il une méthode plus simple pour réaliser cette action ?
    Si ça n'existe pas, est-ce qu'il est possible de créer une méthode générique avec un template (répondez-moi uniquement par oui ou non, ça me permettra de m'exercer avec les templates )

    Merci d'avance pour vos réponses !

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Tu peux utiliser swap au lieu de faire de l'insertion/suppression :
    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
     
    void pushFront(Objet * MonObjet)
    {
        std::list<int>::iterator const it = std::find(ObjetList.begin(), ObjetList.end(), MonObjet);
     
        if(it != list.end())
        {
            // l'objet existe, on l'echange avec le dernier element de la liste
            std::swap(*it, *(ObjetList.rbegin()) );
        }
        else
        {
            // l'objet n'existe pas, on l'insere en fin
            ObjetList.push_back(MonObjet);
        }
    }

  3. #3
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Non, ça ne me va pas : swap déplace le dernier élément de la liste dans ce cas. Et moi, je veux que seul l'élément à mettre à la fin soit déplacé.

    Par exemple, si j'ai une liste avec 1, 2, 3, 4.
    Si je demande à placer 2 en dernier, je veux obtenir 1, 3, 4, 2.

    Avec swap, j'obtiens 1, 4, 3, 2.

  4. #4
    Invité
    Invité(e)
    Par défaut
    est ce que la methode std::list::splice() fait ce que tu veux ?
    http://msdn2.microsoft.com/en-us/library/72fb8wzd.aspx

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Citation Envoyé par toxcct
    est ce que la methode std::list::splice() fait ce que tu veux ?
    http://msdn2.microsoft.com/en-us/library/72fb8wzd.aspx
    Je ne pense pas que ça soit la bonne solution non plus : splice déplace des éléments d'une liste à une autre.

    Citation Envoyé par Eusebe
    Non, ça ne me va pas : swap déplace le dernier élément de la liste dans ce cas.
    Tiens, je n'avais pas lu correctement ton problème . Ta fonction de départ semble être la façon de faire la plus simple. Tu peux en faire une fonction générique avec un template, regarde du côté de std::remove et std::back_inserter.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par roulious
    Je ne pense pas que ça soit la bonne solution non plus : splice déplace des éléments d'une liste à une autre.
    tout comme swap()... mais ya qua lui dire que les deux listes sont en fin de compte la meme liste.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Citation Envoyé par toxcct
    tout comme swap()... mais ya qua lui dire que les deux listes sont en fin de compte la meme liste.
    On peut, mais c'est interdit par le standard:
    Citation Envoyé par Standard C++
    void splice(iterator position, list<T, Allocator>& x); requires &x != this
    Et c'est pareil pour les deux autres formes. Avec un peu de chance, ca marche avec VC++ vu que la MSDN ne donne pas cette précondition, mais le code ne sera plus standard et risque fortement de casser sur d'autres plateformes.

  8. #8
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Oui, avec splice, je peux m'en sortir, mais je dois pour ça créer un itérateur de plus... et je ne suis pas sûr que ce soit plus efficace que le code d'origine (puisque ça fait aussi une suppression / ajout).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        std::list<Objet *>::iterator i = find(ObjetList.begin(), ObjetList.end(), MonObjet);
        std::list<Objet *>::iterator j = i;
        ++j;
        ObjetList.splice(ObjetList.end(), ObjetList, i, j);
    Je vais essayer de faire un template, faut bien y passer un jour (ça sera mon premier )

  9. #9
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    YEEEESSS !

    J'ai réussi à créer mon premier template !

    Pour ceux que ça intéresse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<typename T>
    void MoveBack(std::list<T> & TList, const T & Element)
    {
        TList.remove_if(std::bind2nd(std::equal_to<T>(), Element));
        TList.push_back(Element);
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/07/2008, 09h26
  2. transfert d'élément d'une zone liste
    Par dricks dans le forum VBA Access
    Réponses: 2
    Dernier message: 05/10/2007, 15h25
  3. déplacement d'éléments dans une page
    Par lieto dans le forum Balisage (X)HTML et validation W3C
    Réponses: 14
    Dernier message: 08/06/2006, 12h02

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