我怎麼看它,它似乎工作的一組特殊的地方有偶數同種元素的迴文結構。
您需要返回t
一個元素列表。即。 (null (cdr list))
。
的檢查你有檢查,如果兩個第一要素是相同的,而不是如果第一個和最後一個要素是相同的。
編輯
用遞歸和不使用反向,我能想到的做到這一點,最好的辦法是這樣的:
(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)))
它是如何工作是有一個額外的光標hare
那迭代距離爲tortoise
的兩倍,同時所看到的元素在history
中累積。由於cons
使列表從頭到尾的歷史是所有看到的元素相反,因此應該達到中間時結束。當兔子的cdr
或cddr
爲空時,您處於中間並通過簡單比較可以確定迴文。
EDIT 2
如果移動助手出它更容易跟蹤,看看發生了什麼:
(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
我修改我的代碼,現在它告訴我,我每次都輸入的是一個迴文,任何建議? –
@RileyThomas這是因爲遞歸的論點是正確的,但現在不再。遞歸不再僅在第一個元素髮生變化時纔會完成,但總是會一直進行,直到您遇到基本情況(即空列表)。此外,對一個元素列表的測試應與空列表的測試一起進行。 '(或b)'或'cond'中的單獨條款。現在它是如何在默認情況下完成的,而不是作爲尾部表達。 – Sylwester
我所做的修改似乎現在可行。任何關於如何重寫我的函數的最後一行,以便它仍然執行相同的操作的建議? –