2010-11-18 10 views
4

Ich brauche eine rekursive LISP-Funktion, die die Anzahl der Elemente in einer beliebigen Liste von Zahlen> 3 auflistet. Ich darf lets, loops oder whites nicht verwenden und kann nur CAR verwenden , CDR, SETQ, COND, CONS, APPEND, PROGN, LIST ...Grundlegende LISP-Rekursion, Werte größer als 3 aufzählen

Dies ist mein Versuch, die Funktion:

(defun foo (lst) 
    (COND ((null lst) lst) 
    (T (IF (> (CAR lst) 3) 
     (1+ (foo (CDR lst))) 
     (foo (CDR lst)))))) 

der Funktionsaufruf:

(foo '(0 1 2 3 4 5 6)) 

Antwort

5

Ihr Code ist ziemlich nah an correc t, nur ein kleiner Fehler im Basisfall:

Für die leere Liste geben Sie die leere Liste zurück. Wenn Sie also die Liste (6) haben, fügen Sie 6 zu foo der leeren Liste hinzu, die die leere Liste ist. Das funktioniert nicht, weil Sie keine Nummer zu einer Liste hinzufügen können.

Sie können es leicht beheben, indem foo Rückkehr 0 statt lst wenn lst leer.

Als Stil Hinweis: Mischen cond und if wie folgt, scheint ein bisschen überflüssig. Ich würde es so schreiben, nur mit cond statt:

(defun foo (lst) 
    (cond 
    ((null lst) 
     0) 
    ((> (car lst) 3) 
     (1+ (foo (cdr lst)))) 
    (T 
     (foo (cdr lst))))) 
+0

Ich wusste nicht, Ltg ​​konnte so. Alle Online-Ressourcen sind über das Internet verstreut und nicht leicht zu verstehen ... – toast

+1

Die beste Online-Ressource für geläufige Lisp ist (wahrscheinlich) "The HyperSpec" (http://www.lispworks.com/documentation/HyperSpec/Front /) und ist in der Nähe der umfassendsten Beschreibung von CL. – Vatine

4

Einige stilistischen Punkte:

  • Es gibt keine Notwendigkeit, einige Lisp zu setzen Einbauten in Großbuchstaben geschrieben. Es ist nicht mehr 1958!
  • Aber wenn Sie sind gehen integrierte in Großbuchstaben setzen, warum nicht DEFUN und NULL?
  • Sie haben eine if in den letzten Zweig Ihrer cond. Dies ist redundant. Da der Zweck von cond Testbedingungen ist, warum nicht verwenden?
  • Sie müssen Ihre abschließenden Klammern nicht so ausgrenzen. Niemand zählt heutzutage Klammern, wir haben Klammer-passende Editoren.
  • Lisp verfügt über separate Namespaces für Funktionen und Werte, sodass Sie das Argument lst nicht aufrufen müssen, um Konflikte mit der integrierten Funktion list zu vermeiden.

Wenn Sie dies für echte Programmierung wurden, natürlich würden Sie count-if verwenden:

(count-if #'(lambda (x) (> x 3)) '(0 1 2 3 4 5 6)) 
    ==> 3 
+1

Sorry wegen der stilistischen Probleme (erstes Programm) ... vielleicht hat mein Professor 1958 LISP gelernt - ich kicherte aber. Ich glaube, "count-if" liegt außerhalb des Bereichs der Funktionen, die wir verwenden dürfen. – toast

Verwandte Themen