這兩個函數都可以嵌套cons
。 '(1 2 3)
是(1 . (2 . (3 .()))
和(cons 1 (cons 2 (cons 3 '())))
。嵌套列表可能是cons
的car
嵌套cons
。例如。 ((1 .()) .()) ; ==> ((1))
。
重要的是要能夠看到((1) (2 3))
和理解,這是((1 .()) . ((2 . (3 .())) .()))
因此,如果您要訪問3
這顯然路徑d,一,d,和在相反,你可以構建訪問cadadr
是很重要的。
cons
與cons
在car
部分是樹。當你製作一個走樹的功能時,你需要走car
和cdr
,如果它們是cons
。因此:
;; generic function to walk trees and reduce
;; by combiner every value accessed by term
;; the default argument to combiner is tree-null
(defun accumulate-tree (tree term combiner null-value)
(labels ((rec (tree)
(cond ((null tree) null-value)
((atom tree) (funcall term tree))
(t (funcall combiner (rec (car tree))
(rec (cdr tree)))))))
(rec tree)))
(defun sum-numbers (tree)
(accumulate-tree tree
#'identity
#'+
0))
(defun count-numbers (tree)
(accumulate-tree tree
(lambda (v) (if (numberp v) 1 0))
#'+
0))
(sum-numbers '((1) (2 3) (((4)) 5))) ; ==> 15
(count-numbers '(a b 4 3 (e f 5) . 9)) ; ==> 4
的組合並不需要降低到原子:
(defun reverse-tree (tree)
(accumulate-tree tree
#'identity
(lambda (a d) (cons d a))
'()))
(reverse-tree '((1 2) (3 4)))
; ==> ((nil (nil . 4) . 3) (nil . 2) . 1)
請修正你的函數縮進。你可以使用Emacs。正如他們現在介紹的,你的代碼對於一個Lisper來說是不可讀的。謝謝。 – sds