[英]LISP: take an arbitrary s-expression and reverse every cons node (car and cdr of a node) recursively
因此,在lisp中,列表是con節點的集合,每個節點包含兩個部分。 節點的汽車和該節點的cdr,我將如何反轉每個cons節點?
使用減少:
(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))))
我從交換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))
要遞歸遍歷整棵樹並交換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)
考慮到參數可能包含不正確的列表,對此沒有一個更簡單的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.