So in lisp a list is a collection of cons nodes, each node has two parts to it. The car of the node and the cdr of that node, how would I go about reversing each cons node?
Using reduce:
(defun reverse-conses (list)
(reduce (lambda (x acc) (cons acc x)) list :initial-value nil :from-end t))
Recursively:
(defun reverse-conses (list)
(if (null list) nil
(cons (reverse-conses (cdr list)) (car list))))
I'm starting with a single function that swaps a cons cell.
(defun swap-cons (cns)
(cons (cdr cns)
(car cns)))
Let's test it:
> (swap-cons (cons 1 2))
(2 . 1)
> (swap-cons (cons 1 (cons 2 3)))
((2 . 3) . 1)
So this works. Now we just need to map this function over the input list
(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))
To recursively go through a whole tree and swap car
and cdr
you can do something like this:
(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)
Considering the argument can consist of improper lists there isn't a simpler solution to this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.