2016-06-13 11 views
1

Wie kann ich verhindern, dass der doppelrekursive Aufruf an (f (Auto l)) ohne set/setq/setf?Lisp: Verhindern doppelten Aufruf der rekursiven Funktion

(defun f(l) 
    (cond 
     ((null l) nil) 
     ((listp (car l)) (append (f (car l)) (f (cdr l)) (car (f (car l))))) 
     (T (list (car l))) 
    ) 
) 

Sie denken, das folgende löst es?

(defun f(l) 
    (cond 
    ((null l) nil) 
    ((listp (car l)) 
     (funcall #'(lambda(ff) (append ff (f (cdr l)) (list (car ff)))) (f (car l)))) 
    (T (list (car l))) 
    ) 
) 
+0

Dies wird auf Ihre Frage nicht direkt, aber ich habe nicht, was diese Funktion tun soll. Kannst du etwas erklären? – coredump

+0

Sie müssen es nur überprüfen. Es ist eine Übung ... Das ist alles, was es gegeben ist. Sie müssen die Funktionalität herausfinden und beibehalten, aber vermeiden Sie den zweiten rekursiven Aufruf von (f (car l)), ohne set/setq/setf zu verwenden. – esbej

+0

Ich refaktorierte den Code (http://pastebin.com/raw/N0Aj8Qsq) und ich würde erwarten, dass append auf richtigen Listen arbeiten, deshalb habe ich Assertions hinzugefügt. Die Funktion arbeitet in entarteten Fällen mit NILs. Aber du baust niemals ein '(foo head)' 'so an, dass sein erstes Element eine nicht leere Liste ist, weil der Basisfall der Rekursion' (list head) 'ist mit' head' einer nicht-list. Ersetzen Sie den Körper der letzten Klausel durch '(list (list head))' stellt sicher, dass die Funktion etwas zurückgibt, wenn sie eine korrekte Liste als Eingabe erhält. Ich erkenne, dass dies für diese Übung wahrscheinlich nicht wichtig ist. – coredump

Antwort

4

Ihr Versuch ist in Ordnung, aber ist in der Regel wie folgt geschrieben:

... 
(bar (foo abcde)) 
... 
(baz (foo abcde)) 
... 

->

(let ((r (foo abcde))) 
    ... 
    (bar r) 
    ... 
    (baz r) 
    ...) 

auch beachten:

(funcall #'(lambda (foo) ...) bar) 

in Common Lisp geschrieben werden können wie:

((lambda (foo) ...) bar) 

oder bevorzugt, wie bereits erwähnt, als:

(let ((foo bar)) 
    ...) 
+0

Danke für das Aufräumen! Ich habe noch keine Gewohnheiten mit CLisp, also danke, dass du den Code sauber gemacht hast! – esbej