LISP:采用任意的s表达式并递归地反转每个cons节点(节点的car和cdr)

时间:2015-02-10 03:29:03

标签: list lisp cons

因此在lisp中,列表是cons节点的集合,每个节点都有两个部分。节点的汽车和该节点的cdr,我将如何逆转每个cons节点?

3 个答案:

答案 0 :(得分:2)

使用reduce:

(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))))

答案 1 :(得分: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))

答案 2 :(得分:0)

要递归遍历整棵树并交换carcdr,您可以执行以下操作:

(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)

考虑到参数可能包含不正确的列表,因此没有更简单的解决方案。