因此,在 lisp 中,列表是 cons 节点的集合,每个节点都有两个部分。节点的汽车和该节点的 cdr,我将如何反转每个 cons 节点?
问问题
284 次
3 回答
2
使用减少:
(defun reverse-conses (list)
(reduce (lambda (x acc) (cons acc x)) list :initial-value nil :from-end t))
递归:
(defun reverse-conses (list)
(if (null list) nil
(cons (reverse-conses (cdr list)) (car list))))
于 2015-02-10T04:47:10.467 回答
1
我从一个交换 cons 单元格的函数开始。
(defun swap-cons (cns)
(cons (cdr cns)
(car cns)))
让我们测试一下:
> (swap-cons (cons 1 2))
(2 . 1)
> (swap-cons (cons 1 (cons 2 3)))
((2 . 3) . 1)
所以这行得通。现在我们只需要将这个函数映射到输入列表上
(defun swap-conses (lst)
(mapcar #'swap-cons
lst))
> (swap-conses '((1 . 2)))
((2 . 1))
> (swap-conses '((1 . 2) (3 . 4)))
((2 . 1) (4 . 3))
> (swap-conses '((1 2)))
(((2) . 1))
> (swap-conses '((1 . 2) (3 4) (5 6 7)))
((2 . 1) ((4) . 3) ((6 7) . 5))
于 2015-02-10T05:25:54.843 回答
0
要递归地遍历整个树并交换car
,cdr
您可以执行以下操作:
(defun reverse-conses (tree)
(if (consp tree)
(cons (reverse-conses (cdr tree))
(reverse-conses (car tree)))
tree))
(reverse-conses (cons 1 2)) ; ==> (2 . 1)
(reverse-conses '(1 2 3)) ; ==> (((nil . 3) . 2) . 1)
(reverse-conses '(1 (2 3) 4)) ; ==> (((nil . 4) (nil . 3) . 2) . 1)
考虑到该论点可能包含不正确的列表,因此没有更简单的解决方案。
于 2015-02-11T14:22:55.320 回答