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 Recursive en Clisp


Sujet :

Lisp

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cuba

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2014
    Messages : 10
    Points : 7
    Points
    7
    Par défaut Fonction Recursive en Clisp
    Salut tout le monde

    J'ai un petit probleme avec Clisp, je dois faire une fonction qui filtre une liste et garde seulement les éléments voulu. Une version de cette fonction doit n'avoir qu'un seul argument , la liste a trier et donc l’élément a trier est défini dans la fonction.

    Ça j'y arrive mais des que je veux modifier cette même fonction pour qu'elle prenne en compte un deuxième argument qui serai l’élément a trier ça coince :/

    Le truc est que quand je fais cette fonction avec une boucle iterative ca marche mais des que j'en fais une fonction recursive ca marche pas.

    ---Fonction avec boucle itérative--- Fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (defun garde (x liste &aux bassine)
    (setq bassine nil)
    (loop
            (cond
                    ((not liste) (return bassine))
                    ((equal (car liste) x)(push (pop liste) bassine))
                    ((pop liste)) )))))    
     
    (garde 'o '(o o o & o &))
    (O O O O)
    ---Fonction Récursive et élément connu (o)--- Fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    (defun garde-o (liste)
            (cond
                    ((not liste) nil)
                    ((equal (car liste) 'o) (cons (car liste) (garde-o(cdr liste)) ))
                    ((not (equal (car liste) 'o)) (garde-o(cdr liste)) )) )
     
    (garde-o '(o o o & o &))
    (O O O O)
    ---Fonction Récursive et élément inconnu (x)--- Fonctionne Pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (defun garde (x liste)
    (cond
            ((not liste) nil)
            ((not (equal (car liste) x)) (garde(x (cdr liste))))
            ((equal (car liste) x) (cons (car liste) (garde(x (cdr liste)))))))
     
    (garde '(o o o)'o)
     
     
        *** - EVAL: undefined function X

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cuba

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2014
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Syriano56 Voir le message
    Salut tout le monde

    J'ai un petit probleme avec Clisp, je dois faire une fonction qui filtre une liste et garde seulement les éléments voulu. Une version de cette fonction doit n'avoir qu'un seul argument , la liste a trier et donc l’élément a trier est défini dans la fonction.

    Ça j'y arrive mais des que je veux modifier cette même fonction pour qu'elle prenne en compte un deuxième argument qui serai l’élément a trier ça coince :/

    Le truc est que quand je fais cette fonction avec une boucle iterative ca marche mais des que j'en fais une fonction recursive ca marche pas.

    ---Fonction avec boucle itérative--- Fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (defun garde (x liste &aux bassine)
    (setq bassine nil)
    (loop
            (cond
                    ((not liste) (return bassine))
                    ((equal (car liste) x)(push (pop liste) bassine))
                    ((pop liste)) )))))    
     
    (garde 'o '(o o o & o &))
    (O O O O)
    ---Fonction Récursive et élément connu (o)--- Fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    (defun garde-o (liste)
            (cond
                    ((not liste) nil)
                    ((equal (car liste) 'o) (cons (car liste) (garde-o(cdr liste)) ))
                    ((not (equal (car liste) 'o)) (garde-o(cdr liste)) )) )
     
    (garde-o '(o o o & o &))
    (O O O O)
    ---Fonction Récursive et élément inconnu (x)--- Fonctionne Pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (defun garde (x liste)
    (cond
            ((not liste) nil)
            ((not (equal (car liste) x)) (garde(x (cdr liste))))
            ((equal (car liste) x) (cons (car liste) (garde(x (cdr liste)))))))
     
    (garde '(o o o)'o)
     
     
        *** - EVAL: undefined function X
    Aye Resolu ! ^^

    C'est la synthaxe des arguments de la fonction garde qui etaient faux. En effet c'est pas :
    mais :

  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
    Je profite quand même de ton passage pour te proposer 2-3 petites améliorations

    Code LISP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun garde (x liste)
      (cond
        ((null liste) nil) ;; (null liste) est plus idiomatique que (not liste) et probablement plus optimisé (car d'un usage plus restreint)
        ((equal (car liste) x) (cons (car liste) (garde x (cdr liste)))) ;; equal = 1 appel de fonction / not equal = 2 appels de fonctions => une petite optimisation pcq:
        (T (garde x (cdr liste)))) ;; pas la peine de formuler la dernière condition, puisque c'est la seule qui reste! un simple T suffit

    plutôt que:

    (defun garde (x liste)
    (cond
    ((not liste) nil)
    ((not (equal (car liste) x)) (garde(x (cdr liste))))
    ((equal (car liste) x) (cons (car liste) (garde(x (cdr liste)))))))

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cuba

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2014
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Merci ! En effet ça simplifie le code comme ça Mais je maitrise pas assez t pour y penser tout le temps ^^

    Mnt j'ai une autre fonction qui construit, à partir d'une liste incluant des sous-listes, la liste des sous-listes commençant par un nombre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    (defun nombres (liste)
    (cond
    ((not liste) nil)
    ((and (listp (car liste)) (numberp (car(car liste)))) (cons (car liste) (nombres (cdr liste))) )
    ((nombres (cdr liste))) ) )
     
    (nombres '((2 d b) c (d) (4 f) (e g x) f))
    ((2 D B) (4 F))
    celle-ci marche mais je voudrais la modifier pour quelle compte au lieu de construire une liste donc j'ai fait ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun nombres (liste)
    (cond
    ((not liste) 0)
    ((and (listp (car liste)) (numberp (car(car liste)))) (+1 (nombres (cdr liste))))
    ((nombres (cdr liste)))))
    Mais a chaque fois j'ai cette erreur que je ne comprend pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    *** - SYSTEM::%EXPAND-FORM: invalid form (1 (NOMBRES (CDR LISTE)))
    The following restarts are available:
    ABORT          :R1      Abort main loop

  5. #5
    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
    (defun nombres (liste)
    (cond
    ((not liste) 0)
    ((and (listp (car liste)) (numberp (car(car liste)))) (+1 (nombres (cdr liste))))
    ((nombres (cdr liste)))))
    En effet, cond prend comme arguments un nombre variable de listes, dont le premier élément est une condition, le deuxième l'expression à évaluer si la condition est vraie.
    Or la dernière liste en argument de cond dans ton programme n'est constituée que de l'expression à évaluer. Il aurait fallu rajouter une condition au début, comme cela:

    Code LISP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun nombres (liste)
      (cond
        ((not liste) 0)
        ((and (listp (car liste)) (numberp (car(car liste)))) (+1 (nombres (cdr liste))))
        (T (nombres (cdr liste))))) ;; T est la condition toujours vraie. Si tu veux un truc qui te parle plus, tu peux aussi utiliser :else à la place, par ex: (:else (nombres (cdr liste))

    Par ailleurs tes fonctions utilisent toujours le même pattern de récursion, capturé par la fonction reduce:

    Code LISP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun filtre-liste-nombres (lst)
    	   (reduce 
    	    (lambda (x y) (if (numberp (car x)) (cons x y) y))
    	    lst
    	    :from-end T :initial-value Nil))

    Code LISP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun compte-liste-nombres (lst)
    	   (reduce 
    	    (lambda (x y) (if (numberp (car x)) (+ 1 y) y))
    	    lst
    	    :from-end T :initial-value 0))

    Ce pattern (qui s'appelle fold = plier dans d'autres langages) est l'objet d'un billet de mon blog que je te recommande modestement :
    http://www.developpez.net/forums/blo.../b405/origami/

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cuba

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2014
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Merci pour la réponse rapide !

    Mais quand je compile ton code cad avec le T cela ne change rien, toujours la même erreurs

    Je finis mes DM en Clisp après je verrais le lien Merci !

  7. #7
    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
    Mais quand je compile ton code cad avec le T cela ne change rien, toujours la même erreurs
    Je l'ai mis dans ma boucle REPL, en effet il y avait un autre problème, tu as oublié l'espace entre + et 1
    ((and (listp (car liste)) (numberp (car(car liste)))) (+1 (nombres (cdr liste))))
    Et +1 n'est pas un symbole!

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cuba

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2014
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Merci !

    Au fait j'ai pas résister je suis aller voir le lien et la je suis remonter jusqu'a (Poker time!) pour comprendre

  9. #9
    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,

    Un post en passant et pour me joindre au jeu de l'optimisation de la fonction garde, en signalant qu'il y en a une petite qui a été oublié...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun garde (x liste)
      (cond
        ((null liste) nil) 
        ((equal (car liste) x) (cons x (garde x (cdr liste)))) ;; si (equal (car liste) x) vrai alors "conser" x et plus économe que (car liste)
        (T (garde x (cdr liste)))))
    A+

  10. #10
    Membre actif
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2013
    Messages : 152
    Points : 275
    Points
    275
    Par défaut
    +1 est le nombre « un ».
    1+ est le nom de la fonction « ajouter un »
    Common Lisp est le nom du language.
    CL est en une abréviation.
    (GNU) Clisp est une réalisation obsolète du langage.

Discussions similaires

  1. [C#] probleme avec une fonction recursive
    Par K_!!! dans le forum ASP.NET
    Réponses: 2
    Dernier message: 01/08/2006, 18h22
  2. [Debutante] Fonction recursive avec un pointeur
    Par kidney dans le forum Débuter
    Réponses: 9
    Dernier message: 25/03/2006, 08h08
  3. Réponses: 3
    Dernier message: 22/12/2005, 11h20
  4. [XSL]Probleme fonction recursive
    Par Le-Cortex dans le forum XSL/XSLT/XPATH
    Réponses: 9
    Dernier message: 12/12/2005, 15h10
  5. probleme sql, fonction recursive
    Par CaptainChoc dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/11/2005, 01h45

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