3 Stimmen

Common Lisp: Warum verursacht diese Funktion eine unendliche Rekursion?

Ich versuche, eine Funktion (lnn; list-not-nil) ähnlich wie list zu schreiben, die nur Werte anhängt, die nicht nil sind.

(list nil 3) --> (NIL 3)
(lnn nil 3) --> (3)

Hier ist der Code, den ich bis jetzt habe. Aus irgendeinem Grund verursacht es unendliche Rekursion auf jede Eingabe, die ich versuche.

(defun lnn (&rest items)
  (lnn-helper nil items))

(defun lnn-helper (so-far items)
   (cond ((null items)
           so-far)
     ((null (car items))
      (lnn-helper so-far (cdr items)))
     (t (lnn-helper (append so-far (list (car items))) (cdr items)))))

Irgendwelche Ideen? Ich danke Ihnen vielmals.

4voto

Matthias Benkard Punkte 15177
(defun lnn-helper (so-far &rest items)
  ...)

Mit dieser Argumentliste, items wird nie sein nil wenn Sie immer anrufen lnn-helper mit zwei Argumenten. Entfernen Sie die &rest Spezifizierer, und es wird funktionieren.

2voto

danlei Punkte 13862

Die Antwort von Matthias hätte helfen sollen. Beachten Sie auch, dass dies nur eine einfache Reduzierung ist:

(defun lnn (&rest elements)
  (reduce (lambda (elt acc) (if elt (cons elt acc) acc))
          elements
          :from-end t
          :initial-value nil))

Oder sogar (weniger effizient):

(defun lnn (&rest elements)
  (reduce #'cons (remove nil elements) :from-end t :initial-value nil))

Dann:

(defun lnn (&rest elements)
  (remove nil elements))

:)

P.S.: Ich weiß, dass dies wahrscheinlich nur eine Übung in Rekursion war, aber SCNR.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X