Wie ich es sehe es scheint.
Sie müssen t
für eine Elementliste zurückgeben. dh. (null (cdr list))
.
Die Prüfung, die Sie überprüfen, ob die beiden ersten Elemente identisch sind, wenn das erste und das letzte Element identisch sind.
EDIT
Der beste Weg, dies mit Rekursion zu tun und ohne umkehren mit, dass ich denken kann, ist auf diese Weise:
(defun palindromep (list)
(labels ((aux (history tortoise hare)
(cond ((null hare) (equal tortoise history))
((null (cdr hare)) (equal (cdr tortoise) history))
(t (aux (cons (car tortoise) history)
(cdr tortoise)
(cddr hare))))))
(aux '() list list)))
Wie es funktioniert, ist eine zusätzliche Cursor, indem hare
dass Iteriert die doppelte Distanz wie die tortoise
und gleichzeitig wird das gesehene Element in history
akkumuliert. Da Listen von Ende zu Anfang erstellt, ist die Geschichte alle gesehenen Elemente in umgekehrter Reihenfolge und sollte daher dem Ende entsprechen, wenn Sie die Mitte erreicht haben. Wenn entweder cdr
oder cddr
von Hase Null ist, sind Sie in der Mitte und können Palindrom durch einen einfachen Vergleich ermitteln.
EDIT 2
Wenn Sie bewegen, um den Helfer heraus, dass es einfacher ist, zu verfolgen und sehen, was geschieht:
(defun aux (history tortoise hare)
(cond ((null hare) (equal tortoise history))
((null (cdr hare)) (equal (cdr tortoise) history))
(t (aux (cons (car tortoise) history)
(cdr tortoise)
(cddr hare)))))
(defun palindromep (list)
;; just calls helper
(aux '() list list))
;; trace the helper
(trace aux)
(trace equal) ; you might need to follow instructions to unlock
(palindromep '(1 2 3 3 2 1))
0: (AUX NIL (1 2 3 3 2 1) (1 2 3 3 2 1))
1: (AUX (1) (2 3 3 2 1) (3 3 2 1))
2: (AUX (2 1) (3 3 2 1) (2 1))
3: (AUX (3 2 1) (3 2 1) NIL)
4: (EQUAL (3 2 1) (3 2 1))
4: EQUAL returned T
3: AUX returned T
2: AUX returned T
1: AUX returned T
0: AUX returned T
==> T
(palindromep '(1 2 3 4 5 6))
0: (AUX NIL (1 2 3 4 5 6) (1 2 3 4 5 6))
1: (AUX (1) (2 3 4 5 6) (3 4 5 6))
2: (AUX (2 1) (3 4 5 6) (5 6))
3: (AUX (3 2 1) (4 5 6) NIL)
4: (EQUAL (4 5 6) (3 2 1))
4: EQUAL returned NIL
3: AUX returned NIL
2: AUX returned NIL
1: AUX returned NIL
0: AUX returned NIL
==> NIL
ich meinen Code überarbeitet und jetzt ist es mir zu sagen, alles, was ich geben Sie eine Palindrom, irgendwelche Vorschläge? –
@RileyThomas Das ist, weil das Argument der Rekursion korrekt war, aber nicht mehr. Die Rekursion wird nicht mehr nur ausgeführt, wenn das erste Element funktioniert, sondern immer weitergeht, bis Sie den Basisfall, die leere Liste, treffen. Auch der Test für eine Elementliste sollte zusammen mit dem Test für eine leere Liste durchgeführt worden sein. '(oder a b)' oder als separate Begriffe im 'cond'. Wie es jetzt ist, ist es immer im Standardfall und nicht als Tail-Ausdruck gemacht. – Sylwester
die Revision, die ich gemacht habe, scheint jetzt zu funktionieren. Irgendwelche Vorschläge, wie ich die letzte Zeile meiner Funktion so umschreiben könnte, dass sie immer noch dasselbe tut? –