2017-02-19 4 views
-1

Ich schreibe eine Funktion, die eine Liste von einem Benutzer nimmt und diese Liste in eine vereinfachte Liste abflachen wird. Die Funktion scheint nur das erste Element auf der Liste und nicht den Rest zurückzugeben? Irgendwelche Vorschläge, warum es das macht?Warum gibt mir meine Lisp-Funktion diese Ausgabe?

Beispiel:

> (flatten '(a() b (c d)) 
(a b c d) 

Das ist, was ich bisher

(defun flatten (list) 
(cond 
    ((null list)t) 
     (list (first list) (rest list)) 
     (t(append (flatten (first list)) 
       (flatten (rest list))) 
    (t(cons (first list (flatten (rest list)))))))) 

Der Ausgang wird geben

> (flatten '(a() b (c d))) 
(NIL B (C D)) 
+1

'(Liste (erste Liste))' - weil Sie es sagen, nur das erste Element zurückgeben? – melpomene

+0

@melpomene Ich habe gerade realisiert, was ich getan habe, danke für die Klarstellung –

+4

Jetzt sagt dein Code: Wenn '(Nullliste)' (d. H. Wenn 'Liste' leer ist/nil), gib 't' zurück. Andernfalls, wenn "list" (d. H. Wenn list nicht-leer ist/nicht nil), hole das erste Element und ignoriere es, dann hole den "Rest" (alles außer dem ersten Element) und gebe das zurück. Ihr verbleibender Code ist irrelevant, weil eine der beiden ersten Bedingungen immer wahr ist. – melpomene

Antwort

3

Sie bearbeiten die ursprüngliche Frage mit aktualisiertem Code haben, die macht es zu einem beweglichen Ziel. Derzeit ist der Code das folgende, nachdem ich Emacs fragen sie einrücken mit Mq (Lisp-Modus):

(defun flatten (list) 
    (cond 
    ((null list)t) 
    (list (first list) (rest list)) 
    (t (append (flatten (first list)) 
       (flatten (rest list))) 
     (t (cons (first list (flatten (rest list)))))))) 
;; ^^^ Something is not good, why is the clause indented? 

Klammerung Struktur der Code für den Computer, während Vertiefung ist ein Weg, um diese Struktur zu drucken für menschliche Leser. Diese Redundanz ermöglicht es Ihnen, Probleme im Quellcode zu erkennen, wenn einer nicht mit dem anderen übereinstimmt. Hier ist die (t cons) keine Cond-Klausel, sie ist in der vorherigen Klausel verschachtelt.

Zweitens, wie in den Kommentaren gesagt, cond wird zu der ersten Klausel gehen, für die der Test erfolgreich ist. Wenn Sie (cond (t X) ...) schreiben, würde nichts in dem ... Teil die Bedeutung des Codes ändern, der immer X zurückgibt. In Ihrem Code, testen Sie wie folgt vor:

  1. (null list) prüft, ob listeq-nil ist.
  2. listnicht testen, ob list eine Liste ist. Es gibt ein Prädikat namens listp, das zu erkennen. Wenn Sie list so eingeben, fragen Sie, ob list ein verallgemeinerter wahrer Wert ist, der notwendigerweise wahr ist, wenn Sie zuvor nil ausschlossen (die vorherige Klausel).
  3. Die Standardklausel (t ...) kann nicht verwendet werden, da der vorherige Test nicht fehlschlagen kann. Hier

ist ein Skelett:

(defun flatten (form) 
    (cond 
    ((null list) ...) 
    ((consp list) ...) 
    (t ...))) 

Statt consp Sie listp schreiben konnte, aber beachten Sie, dass per Definition eine Liste entweder nil oder eine cons Zelle, so consp ist ein wenig expliziter und tut Überschneidung mit einem Test für nil nicht. Beachten Sie auch, dass ich immer gegen den Typ der Form teste, der ein Muster ist, das oft gefunden wird. Deshalb möchten Sie vielleicht typecase verwenden.

+1

Dank wäre, nachdem du mit dem Skelett herumgespielt hast, das du mir gegeben hast. Ich konnte es herausfinden –

Verwandte Themen