2010-03-05 7 views
2

j'ai les éléments suivantsprogrammation Scheme trouver des éléments dans les boucles imbriquées

(define itemslist 
    (list 'a1 'b2 'c3 (list 'z1 'z2) 'd5 'e6)) 

Ma méthode pour trouver des articles est inférieure

(define find-item 
    (lambda (item itemslist) 
    (cond ((null? itemslist) #f) 
      ((list? (car itemslist)) 
      (cond ((null? itemslist) #f) 
        (else (find-item item (car itemslist))))) 
      ((equal? stn (car itemslist)) (display "found")) 
      (else (find-stn stn (cdr itemslist))) 
     ) 
    ) 
) 

Avec ma méthode ci-dessus je peux trouver a1, b2, c3, z1 , z2. Mais quand je veux trouver d5 à la suite, il ne retourne rien. Il semble avoir sauté la pile. Btw, je commence juste à apprendre Scheme si simple explication serait mieux.

Un plus qns, que diriez-vous si j'ai

(list 'a1 'b2 'c3 (list 'z1 (list 'y1 'y2) 'z2) 'd5 'e6) 

fait cela fonctionne aussi bien? Merci!

+0

N'oubliez pas de marquer une réponse comme _accepted_ si vous estimez qu'elle est adéquate. – csl

Répondre

4

Oui, vous ignorez les listes.
Exemple:

'(1 '(2 3) 4) 

Si (list? '(2 3)) est vrai, la else partie (externe cond) être évalué de façon 4 est ignorée habitude.
Ainsi, vous placez la pièce else dans le bloc list? ou vous modifiez votre code.

Si le itemlist est un list/pair vous pouvez le passer tout de suite dans un appel récursif si
vous pouvez éviter d'écrire du code comme (car itemslist) prédicats à l'intérieur font ainsi le simple code.

Voici une redessiné la version (simplifiée):

(define (find-item item l) 
    (cond ((equal? item l) #t) 
     ((pair? l) (or (find-item item (car l)) (find-item item (cdr l)))) 
     (else #f))) 

Astuce: vous pouvez pouvez aussi écrire des listes avec '(...) notation au lieu de (list ...), à savoir

(find-item 'z2 '('a1 'b2 'c3 '('z1 '('y1 'y2) 'z2) 'd5 'e6)) 
#t 
(find-item 'e6 '('a1 'b2 'c3 '('z1 '('y1 'y2) 'z2) 'd5 'e6)) 
#t 
+0

Apprécié! J'ai appris quelque chose. – Mintyique

2

Pour écrire plus pour le bien de écrire plus ... Cela s'appelle habituellement un "arbre-promenade" parce qu'une liste imbriquée comme ceci est vraiment un arbre binaire. Les listes sont vraiment composées de paires binaires, donc quand vous avez une paire (l . r), l est la branche gauche de l'arbre et r est la branche droite de l'arbre.

Par exemple, '(1 (2 3) 4) est court pour '(1 . ((2 . (3 .())) . (4 .()))) qui peut être dessiné comme

 . 
    /\ 
    1 . 
    /\ 
    / . 
    //\ 
    . 4 () 
/\ 
2 . 
    /\ 
    3 () 

et à toute paire (l . r), car vous obtient l'arbre gauche et cdr vous obtient le droit. Donc, quand vous écrivez (pair? ls), vous demandez vraiment si vous êtes à une branche dans l'arbre, à quel point vous devez réapparaître sur la branche gauche (car) et la branche droite (cdr). J'espère que cela vous aidera à comprendre les listes.

+0

Je vois. Merci!! – Mintyique

0

Même si vous avez obtenu votre réponse [spécifique], voici quelque chose qui pourrait vous aider avec des questions similaires.

(define describe 
    (lambda (e) 
    (cond #;((list? e) 
      `(list ,@(map describe e))) 
      ((pair? e) 
      `(cons ,(describe (car e)) 
        ,(describe (cdr e)))) 
      ((vector? e) 
      `(vector ,@(map describe (vector->list e)))) 
      ((or (null? e) (symbol? e)) `',e) 
      (else e)))) 

Cette procédure imprime le code qui génère un sexpr donné.Par exemple:

> (describe '(a 2 b 3)) 
(cons 'a (cons 2 (cons 'b (cons 3 '())))) 

Il sera également placer les citations en cas de besoin, il les place avant ou symboles() mais pas avant les chiffres. Lorsque vous êtes à l'aise avec des paires imbriquées, vous pouvez supprimer le #; sur la troisième ligne, pour générer plus de puissance compacte:

> (describe '(a 2 b 3)) 
(list 'a 2 'b 3) 

Ce code peut vous apprendre beaucoup de choses au sujet de citation. Par exemple:

> (describe ''''a) 
(list 'quote (list 'quote (list 'quote 'a))) 
Questions connexes