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 :

Fonction avec des doublets


Sujet :

Lisp

  1. #1
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut Fonction avec des doublets
    Bonjour,

    J'ai deux fonction que je ne trouves pas la réponse total :

    1. Faire une fonction pour récupérer dans une liste le premier de chaque doublet dont le deuxième élément est supérieur à 10.

    '( (1 . 27) (3 . 9) ( (2 . 33) (5 . 27) (4 . 52) (7 . 8) ) (6 . 74) )

    ma fonction est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    (defun atomes (nomber liste)
    (cond
    ((not liste) nil)
    ((and (listp (car liste)) (>=  (cdr (car liste)) nomber))
    (cons (car (car liste)) (atomes nomber (cdr liste))) )
    ((atomes nomber (car (cdr liste)))) ))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [4]> (atomes 10 '( (1 . 27) (3 . 9) ( (2 . 33) (5 . 27) (4 . 52) (7 . 8) ) (6 . 74) ))
    (1 2 5 4)
    Normalement je devais avoir comme résltat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [4]> (atomes 10 '( (1 . 27) (3 . 9) ( (2 . 33) (5 . 27) (4 . 52) (7 . 8) ) (6 . 74) ))
    (1 2 5 4 6)
    2. Modifier la liste pour qu'elle ne contienne plus que les doublets dont le deuxième élément est supérieur à 10.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (defun atomes (nomber liste)
    (cond
    ((not liste) nil)
    ((and (listp (car liste)) (>=  (cdr (car liste)) nomber))
    (rplacd liste (atomes nomber (cdr liste))) )
    ((atomes nomber (car (cdr liste)))) ))

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 35
    Points : 63
    Points
    63
    Par défaut
    Bonjour,

    Ta fonction s'applique à une structure de donnée de type arborescente, tel quelle elle ne parcourt pas l'ensemble de l'arbre et s'arrête à la première extrémité trouvé. C'est pourquoi le nœud qui conduit à la paire pointée (6 . 74) n'est jamais emprunté et 6 ne peut être retourné.

    Tu trouveras pour le parcours de ta liste imbriqué des éléments de réponse dans une discussion dont tu étais à l'origine:
    http://www.developpez.net/forums/d14...e-liste-plate/

    Regarde plus particulièrement dans cette discussion l'usage qu'il est fait de la fonction append pour combiner les appels récursif, de façon à parcourir l'ensemble de l'arbre.

    A+

  3. #3
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    En plus de ce que dit Bruno, il faut faire attention à un autre point, c'est que dans ton cas la liste est à la fois le contenant et le contenu: le contenant, parce que c'est un arbre de doublets, et le contenu, parce qu'un doublet est représenté par une liste. Il faut bien que tu distingues les deux cas dans ta fonction: le cas où listp renvoie T parce que tu es en présence du contenant, et le cas où listp renvoie T également mais que tu es en présence du contenu; tu es donc obligé de modifier tes tests:

    Code LISP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (if (and (listp e) (atom (cdr e))
        (then)  ;; contenu
        (else))  ;; contenant

  4. #4
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    On utilisant append je me retrouve plus perdu qu'avant :sss

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [340]> (defun atomes (nomber liste)
    (cond
    ((not liste) nil)
    ((and (listp (car liste)) (>=  (cdr (car liste)) nomber))
    (append  (atomes nomber (car (car liste))) (atomes nomber (cdr liste))) )
    ((atomes nomber  (cdr liste))) ))
    atomes
    [341]> (atomes 10 '(  (1 . 27)     (3 . 9)     (  (2 . 33)        (5 . 27)        (4 . 52)        (7 . 8) )      (6 . 74) ))
     
    *** - car: 1 is not a list
    Rentrées possibles:
    ABORT          :R1      Abort main loop

  5. #5
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [359]> (defun atomes (nomber liste)
    (cond
    ((atom liste) nil)
    ((and (listp (car liste)) (>=  (cdr (car liste)) nomber))
    (cons   (car (car liste)) (atomes nomber (car (cdr liste))) ))
    (t(append (atomes nomber (car liste)) (atomes nomber  (cdr liste))))))
    atomes
    [360]> (atomes 10 '(  (1 . 27)     (3 . 9)     (  (2 . 33)        (5 . 27)        (4 . 52)        (7 . 8) )      (6 . 74) ))
    (1)



    pourriez vous me dire maintenant pourquoi ça marche toujours pas (((

  6. #6
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Dans ces cas-là, on commence par un cas plus simple et ensuite on le complique.

    Le cas simple c'est la liste simple, pas un arbre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun atomes (number lst)
      (cond 
         ((null lst) nil)
         ((> (cdr (car lst)) 10) (cons (car lst) (atomes number (cdr lst)))
         (T (atomes number (cdr lst))))
    Là tu n'as que deux cas: soit la liste est finie, soit son premier élément est un duplet que tu peux tester.

    Le cas complexe c'est l'arbre: il y a 3 possibilités:
    - soit la liste est vide
    - soit son premier élément est un duplet
    - soit son premier élément est une liste de duplets, une liste de liste de duplets, une liste de liste de liste ... de duplets

    Du coup:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    (defun atomes (number lst)
      (cond
        ((null lst) nil) ;; cas 1: ça n'a pas changé
        ((and (listp (car lst)) (atom (cdr (car lst)))) ;; cas 2: si c'est bien un duplet
         (if (> (cdr (car lst)) number) (cons (car lst) (atomes number (cdr lst))) (atomes number (cdr lst)))) ;; on regarde si > 10 et on garde sinon on passe
        (T ;; cas 3 : si c'est une liste
         (let ((nxt (atomes number (cdr lst)))) ;; on calcule la suite
           (append (atomes number (car lst)) nxt))))) ;; et on la met au bout de notre résultat

  7. #7
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Bonjour,

    Merci pour la réponse,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    (defun atomes (number lst)
      (cond
        ((null lst) nil) 
        ((and (listp (car lst)) (atom (cdr (car liste))))            # atom veut dire que (cdr (car est un atome ???
         (if (> (cdr (car lst)) number) (cons (car (car lst)) (atomes number (cdr lst))) (atomes number (cdr lst))))    est ce qu'on peut renplacer if par (( ??
         (t (setq nxt (atomes number (cdr lst))) (append (atomes number (car lst)) nxt))))

  8. #8
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Oui, atom est une fonction qui teste si son argument est un atome. Tels qu'ils sont représentés, tes duplets sont des listes dont le cdr est un atome.
    Pour le if, tu peux le remplacer par une nouvelle condition mais ça va alourdir la structure:
    cond
    1) listes finie
    2) car list = duplet et duplet < 10
    3) car list = duplet et duplet > 10
    4) sinon...

    ça t'oblige à tester 2 fois si c'est un duplet et 2 fois si c'est supérieur ou inférieur à 10

  9. #9
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2014
    Messages : 208
    Points : 60
    Points
    60
    Par défaut
    Merci j'ai compris, je vais essayer de le faire sans la condition if comme on n'a pas fait cette condition en lisp


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

Discussions similaires

  1. Réponses: 8
    Dernier message: 02/02/2006, 18h13
  2. [Débutant]Fonction avec des flags
    Par @r$£~%[ dans le forum C++
    Réponses: 10
    Dernier message: 22/08/2005, 10h19
  3. Réponses: 6
    Dernier message: 24/02/2005, 09h44
  4. Erreur sur une fonction avec des paramètres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/05/2004, 21h00
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39

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