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

Lisp Discussion :

aplatissement de listes


Sujet :

Lisp

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 39
    Points : 38
    Points
    38
    Par défaut aplatissement de listes
    Bonjour,
    je suis débutant en langage LISP, j'ai essayé en vain de parvenir à une solution d'un exercice, et je cherche une âme charitable pour m'aider, voila l'énoncé de l'exercice

    "Définir le but aplatir( L,L1 ),qui prend une liste L quelconque , avec éventuellement des listes imbriquées , et retourne dans L1 la liste aplatie ( sans imbrication des listes).

    merci d'avance

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 141
    Points : 160
    Points
    160
    Par défaut
    Citation Envoyé par abssef Voir le message
    Bonjour,
    je suis débutant en langage LISP, j'ai essayé en vain de parvenir à une solution d'un exercice, et je cherche une âme charitable pour m'aider, voila l'énoncé de l'exercice

    "Définir le but aplatir( L,L1 ),qui prend une liste L quelconque , avec éventuellement des listes imbriquées , et retourne dans L1 la liste aplatie ( sans imbrication des listes).

    merci d'avance
    Ben on aurais bien voulu voir tes essais ... mais comme je trouve ton problème intéressant je me suis amusé à faire cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    (defun aplati (lst) 
      (if (null lst) 
        'done
        (if (atom (first lst))
          (progn
    	(print (first lst))
    	(setf lst (cdr lst))
    	(aplati lst)
    	)
          (progn 
    	(setf lst (first lst))
    	(aplati lst)))))
    ça marche pour une liste du type: (a (b (c d)))
    mais pas pour une liste du type : (a (b c) (e f g h))

    J'espère que tu finiras le travail tout seul ...

    (suis pas un expert Garulfo corrige mois si mon code est pas très pro)

  3. #3
    Nouveau membre du Club
    Inscrit en
    Octobre 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 39
    Points : 38
    Points
    38
    Par défaut
    merci bien pour ton aide

  4. #4
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Citation Envoyé par rutabagas Voir le message
    [...]
    suis pas un expert Garulfo corrige mois si mon code est pas très pro
    Déjà, ce n'est pas très fonctionnel ! Les setf sont à proscrire. De plus ce n'est pas ce qui est demandé je pense. Tu produis un affichage, l'énoncé parle de retourner une liste.

    La question est aussi de savoir le contexte dans lequel s'est demandé. Par exemple, si son prof vient de lui apprendre la programmation par flots (map, fold etc) ce n'est probablement pas l'approche attendue.

    Maintenant, avant de répondre à Abseff, est-ce que celui-ci a écrit un algorithme ? Sinon, c'est la première chose à faire...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 141
    Points : 160
    Points
    160
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Déjà, ce n'est pas très fonctionnel ! Les setf sont à proscrire. De plus ce n'est pas ce qui est demandé je pense. Tu produis un affichage, l'énoncé parle de retourner une liste.

    La question est aussi de savoir le contexte dans lequel s'est demandé. Par exemple, si son prof vient de lui apprendre la programmation par flots (map, fold etc) ce n'est probablement pas l'approche attendue.

    Maintenant, avant de répondre à Abseff, est-ce que celui-ci a écrit un algorithme ? Sinon, c'est la première chose à faire...
    Merci de tes conseils Garulfo.
    J'ai produit un affichage car effectivement il n'a pas donné de code et je ne voulais pas faire tout son boulot. (L1 ne sera pas dans le bon odre)
    On ne peut pas tomber dans la méfiance maximum et toujours penser que l'étudiant est un tricheur systématiquement et que les profs sont tous parfaits (Je suis prof dans le secondaire (pas d'info) et je connais la maison ...)
    Merci encore pour tes remarques que j'apprécie.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juin 2008
    Messages : 22
    Points : 24
    Points
    24
    Par défaut
    Oui, c'est un problème classique des cours de LISP...
    Tu dois connaître les notions suivantes :
    - les LISTES
    comment savoir si on à affaire à une liste ?
    comment savoir qu'une liste est vide ?
    comment récupérer le premier élément d'une liste ?
    comment retirer le premier élément d'une liste ?
    comment ajouter un élément a une liste ?
    comment concaténer deux listes ?
    - les FONCTIONS et la "récursivité"
    - comment construire une conditionnelle

    Voilà pour les outils...

    Maintenant le mieux pour toi est de trouver la solution par toi même mais si tu veux, voici quand même ma solution sur le principe suivant :
    > (aplatir '(A (A B) (A B (A C X)) ((A B)(C D)(E F)) B))
    (A A B A B (A C X) (A B) (C D) (E F) B)
    Je définit une fonction récursive "aplatir" qui prend une liste comme unique paramètre.
    Si la liste et vide, "aplatir" retourne une liste vide
    Si le premier élément de ma liste et une liste, je le concaténe avec le reste de la liste aplatit.
    Sinon j'ajoute ce premier élément comme premier élément du reste de la liste aplatit.

    Je ne sait pas si c'est vraiment clair... Je pourrais éventuellement te donner le code en Scheme au besoin...

    Maintenant si tu veux un aplatissement total de la liste, je te laisse faire, il ne doit pas manquer grand chose...

  7. #7
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Citation Envoyé par Sygénème Voir le message
    Maintenant le mieux pour toi est de trouver la solution par toi même mais si tu veux, voici quand même ma solution sur le principe suivant : [...]

    Je définit une fonction récursive "aplatir" qui prend une liste comme unique paramètre.
    Si la liste et vide, "aplatir" retourne une liste vide
    Si le premier élément de ma liste et une liste, je le concaténe avec le reste de la liste aplatit.
    Sinon j'ajoute ce premier élément comme premier élément du reste de la liste aplatit.
    Il y a une petite faute de sens. Aplatir doit aplatir tout « l'arbre ». Au final, les feuilles de l'arbre sont dans une liste « plate ». Donc avec ton exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    > (aplatir '(A (A B) (A B (A C X)) ((A B)(C D)(E F)) B))
    (A A B A B A C X A B C D E F B)
    Il ne suffit donc pas de le concaténer.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juin 2008
    Messages : 22
    Points : 24
    Points
    24
    Par défaut
    Arf OK ! je m'attaque au problème alors (en scheme cepandant).

    EDIT : C'était bien plus simple que je l'imaginai intuitivement, il suffit juste d'aplatir aussi "le premier élément de ma liste qui et une liste" avant de le concaténer...

    soit en scheme le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    (define (aplatir L)
      (cond
        ((null? L) ())
        ((pair? (car L)) (append (aplatir (car L)) (aplatir (cdr L))))
        (else (cons (car L) (aplatir (cdr L))))))

  9. #9
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Et maintenant... dans une forme récursive terminale ??

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juin 2008
    Messages : 22
    Points : 24
    Points
    24
    Par défaut
    Voilà, j'ai (je pense) réussi ! Ce fut plus compliquer que j'aurais cru et mon ego en à prit un coup ^^

    Donc voici ma solution, avec en rouge les passages qui m'ont posé problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    (define (aplatir L)
      (define (traitement L X)
        (cond
          ((null? L) X)
          ((pair? (car L)) (traitement (cdr L) (traitement (car L) X)))
          (else (traitement (cdr L) (append X (list (car L)))))))
       (traitement L ()))

  11. #11
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Ta fonction est correcte mais lente, à cause du append elle est en O(n²) au lieu d'être en O(n) comme elle peut l'être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (define (flatten L)
      (define (flatten-rev rest flattened)
        (cond
          ([null? rest] flattened)
          ([pair? (car rest)] 
           (flatten-rev (cdr rest) 
                        (flatten-rev (car rest) flattened)))
          (else 
           (flatten-rev (cdr rest) (cons (car rest) flattened)))))
      (reverse (flatten-rev L ())))
    --
    Jedaï

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juin 2008
    Messages : 22
    Points : 24
    Points
    24
    Par défaut
    Effectivement çà marche aussi comme çà !
    En fait si tu regarde mon code, les fonctions provoquant le O(n²) sont en rouge ; ma première idée était bien (cons (car L) ... mais étrangement çà transformait la liste (A B C) en liste (().A ().B ().C).
    M'est d'avis que j'ai du me tromper dans le parenthèsage...

Discussions similaires

  1. Comment représenter un tree, aplatissable sous forme de liste ?
    Par mamelouk dans le forum Autres Logiciels
    Réponses: 4
    Dernier message: 25/02/2008, 22h32
  2. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25
  3. liste d'objets
    Par Pierrot dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2002, 09h56
  4. Compter le nombre ligne listée (COUNT) ?
    Par StouffR dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/09/2002, 09h41
  5. Listes déroulantes liées entre elles
    Par denisC dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 27/07/2002, 15h53

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