如何反转列表以使每个子列表也被反转?这就是我到目前为止所做的:
(defun REV (L)
(cond
((null L) nil)
((listp L)
(append
(REV (cdr L))
(list (car L))))
(t
(append
(REV (cdr L))
(list (car L))))))
答案 0 :(得分:5)
你走在正确的轨道上,但是你的最后两个条件具有相同的动作,这应该表明其中一个没有做它应该做的事情。实际上,第二个条件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))
正如您所看到的,唯一的区别是您测试第一个元素是否为列表,如果是,则在追加第一个元素之前将其反转。
答案 1 :(得分:2)
我会这样写:
(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)))
答案 2 :(得分:0)
听起来像是一个家庭作业问题:)
看起来你是通过编写常规反向代码开始的。我会给你一个提示:第二个条件(listp L)不太正确(它总是如此)。你想检查是否有其他东西是列表。
答案 3 :(得分:0)
dmitry_vk的答案(在大多数lisps中可能比在前面的例子中使用append更快)以更加低调的方式:
(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))))