如何顛倒一個列表,使每個子列表也被顛倒?這是我到目前爲止有:LISP:多級遞歸反轉函數
(defun REV (L)
(cond
((null L) nil)
((listp L)
(append
(REV (cdr L))
(list (car L))))
(t
(append
(REV (cdr L))
(list (car L))))))
如何顛倒一個列表,使每個子列表也被顛倒?這是我到目前爲止有:LISP:多級遞歸反轉函數
(defun REV (L)
(cond
((null L) nil)
((listp L)
(append
(REV (cdr L))
(list (car L))))
(t
(append
(REV (cdr L))
(list (car L))))))
你在正確的軌道上,但最後的兩個條件有相同的動作,這應該表明其中一個沒有做它應該做的。事實上,第二個條件listp
的情況是不正確的,因爲當它是一個列表時,您需要附加該列表的反向而不是未修改的列表。一個可能的解決方案:
(defun reverse (l)
(cond ((null? l) nil)
((listp (car l)) (append (reverse (cdr l))
(list (reverse (car l)))))
(t
(append (reverse (cdr l))
(list (car l))))))
> (reverse '((1 2 3) (4 5 6)))
((6 5 4) (3 2 1))
正如你看到的,唯一的區別是,你測試,如果第一個元素是一個列表,如果是,你追加之前扭轉的第一要素。
聽起來像一個家庭作業問題:)
看起來你寫的常規反向代碼開始。我會給你一個提示:第二個條件(listp L)不是很對(它永遠是真的)。你想要檢查是否有其他東西是一個列表。
我會寫這樣:
(defun reverse-all (list)
(loop
with result = nil
for element in list
if (listp element)
do (push (reverse-all element) result)
else do (push element result)
finally (return result)))
dmitry_vk的回答(這可能是在大多數的Lisp比使用附加在前面的例子更快)更lispish方式:
(defun reverse-all (list)
(let ((result nil))
(dolist (element list result)
(if (listp element)
(push (reverse-all element) result)
(push element result)))))
甚至:
(defun reverse-all (list)
(let ((result nil))
(dolist (element list result)
(push
(if (listp element) (reverse-all element) element)
result))))
短一點: (defun定義我的反轉(L)(我的反向(cdr l)) (list(if(listp(car l))(my-reverse(car l))(car l))))) ) – jlf 2009-09-14 23:59:57