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

SL & STL C++ Discussion :

Itérateur sur l'avant-dernier élément d'une liste


Sujet :

SL & STL C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Points : 8
    Points
    8
    Par défaut Itérateur sur l'avant-dernier élément d'une liste
    Bonsoir à tous,

    Je me pose la question suivante :
    Puis-je faire en sorte de parcourir une liste grâce à un itérateur jusqu'à son avant-dernier élément ?

    Un code du genre suivant ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(list<int>::iterator it = maliste.begin() ; it != maliste.end()-1 ; it++)
    Merci beaucoup pour votre aide

    EDIT: résolu : il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(list<int>::iterator it = maliste.begin() ; it != --(maliste.end()) ; it++)

  2. #2
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour,
    Le problème est "maliste.end()-1"
    Un itérateur de liste ne possède pas d'opérateur d'addition ou de soustraction, en raison des propriétés fondamentales des listes.

    Car, dans une liste doublement chainée, chaque maillon connait :
    le maillon suivant : iterator++ (ou ++iterator) est possible.
    le maillon précédent : iterator-- (ou --iterator) est possible
    Mais pas les autres maillons : iterator + N (ou iterator - N) est impossible

    Il faut donc plutôt partir sur qqchose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::list<int>::iterator avant_dernier = --liste.end();
    Mais ça sera surement probablement plus compliqué, car "avant-dernier" n'est pas vraiment bien défini pour les listes à 0 et à 1 élément...

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Pourtant on peut faire std::advance(it,N), N étant un entier signé quelconque.
    Autre solution donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::list<int>::iterator avant_dernier = liste.end();
    std::advance(avant_dernier,-1);

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Merci bien camboui,
    ça me sera utile dans le futur.

  5. #5
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Oui c'est vrai, DJM400, je n'y avais pas pensé, mais std::advance est probablement la meilleure solution, vu que cette fonction choisie automatiquement la bonne manière d'itérer en fonction du type d'itérateur

    Avec Visual, si l'itérateur est un itérateur de vecteur, on tombe sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class _RI, class _Diff> inline
    void _Advance(_RI& _Where, _Diff _Off, random_access_iterator_tag)
    {   // increment iterator by offset, random-access iterators
       _Where += _Off;
    }
    mais si c'est une liste...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<class _BI, class _Diff> inline
    void _Advance(_BI& _Where, _Diff _Off, bidirectional_iterator_tag)
    {   // increment iterator by offset, bidirectional iterators
       for (; 0 < _Off; --_Off)
          ++_Where;
       for (; _Off < 0; ++_Off)
          --_Where;
    }

  6. #6
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    Sinon, avec boost:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::list<int>::iterator avant_dernier = prior(liste.end());

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Salut,
    Citation Envoyé par camboui Voir le message
    Pourtant on peut faire std::advance(it,N), N étant un entier signé quelconque.
    Autre solution donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::list<int>::iterator avant_dernier = liste.end();
    std::advance(avant_dernier,-1);
    Si ce n'est que l'itérateur renvoyé par end() pointe, non pas sur le dernier élément de la liste, mais sur... ce qui le suit...

    Cela implique que tu n'accède pas à l'avant dernier élément dans le cas présent, mais... au dernier élément

    Pour accéder à l'avant dernier élément de la lsite, ce serait plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::list<int>::iterator avant_dernier = liste.end();
    std::advance(avant_dernier,-2);


    Une autre solution pourrait être de prendre la liste "à l'envers" et d'utiliser un reverse_iterator et rbegin(), qui nous donne un itérateur le premier élément en commençant par sa fin...

    Nous pouvons donc accéder à l'avant dernier élément avec un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::list<int>::/*const_*/reverse_iterator it = laliste.rbegin(); //dernier itérateur
    ++it; // sautons à l'avant dernier
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Tu as raison... parce que tu as sorti le code de son contexte
    En reprenant le contexte du tout premier post, il s'agit bien de faire "-1" dans une boucle.
    Mais quitte à être pragmatique, si le container est vide on aura un joli crash

  9. #9
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Pas avec advance. Il se passera rien tout cours .
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

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

Discussions similaires

  1. Récupérer dernier élément d'une List
    Par loupdu45 dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 07/01/2012, 02h57
  2. Réponses: 0
    Dernier message: 30/10/2008, 12h29
  3. Récupérer l'avant dernier élément d'une table
    Par markoBasa dans le forum SQL
    Réponses: 1
    Dernier message: 22/08/2008, 09h37
  4. Dernier élément d'une liste
    Par nabil148911 dans le forum SQL
    Réponses: 1
    Dernier message: 03/08/2007, 12h26
  5. Réponses: 3
    Dernier message: 25/10/2006, 19h08

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