:
(define (tree-accumulate tree)
(if (pair? tree)
(apply + (car tree) (map tree-accumulate (cdr tree)))
(+ tree)))
例如: (树积累'(1 1 1(1(1(1 1 1)1 1)1 1(1 1 1(1 1 1)))))) ==> 18
如何编写树形图函数以便您可以编写:
(define (tree-accumulate tree)
(tree-map + tree))
尝试:
(define (tree-map f tree)
(if (pair? tree)
(apply + (car tree) (map (tree-map (cdr tree)) )
(f tree)))
但问题是如何放入f param :( map(tree-map(cdr tree)) 适用于仍在工作?
答案 0 :(得分:1)
正如已经指出的那样,这不是地图而是折叠。
尽管如此,您只需要将递归应用程序“包装”在另一个函数中,这样就可以传递f
:
(define (tree-fold f tree)
(if (pair? tree)
(apply f (car tree) (map (lambda (t) (tree-fold f t)) (cdr tree)))
(f tree)))
实际地图可能如下所示:
(define (tree-map f tree)
(if (pair? tree)
(cons (f (car tree)) (map (lambda (t) (tree-map f t)) (cdr tree)))
(f tree)))
答案 1 :(得分:0)
嗯,这样的函数不会被称为map
。它实际上更像是fold
,类似于foldr
或foldl
。所以无论如何,这是使用tree-accumulate
函数的tree-foldl
的一种可能定义:
(define (tree-accumulate tree)
(tree-foldl + 0 tree))
0
作为第二个参数是基本情况,因为树中没有叶子。 tree-foldl
函数可以这样定义:
;; (Treeof A) is one of:
;; - A
;; - (Listof (Treeof A))
;; Where the A type can't include lists.
;; tree-foldl : [A B -> B] B (Treeof A) -> B
;; Where the A type can't include lists.
(define (tree-foldl f base tree)
(cond [(not (list? tree))
(f tree base)]
[else
(tree-foldl/list f base tree)]))
;; tree-foldl/list : [A B -> B] B (Listof (Treeof A)) -> B
;; Where the A type can't include lists.
(define (tree-foldl/list f base tree)
(cond [(empty? tree)
base]
[else
(tree-foldl/list f
(tree-foldl f base (first tree))
(rest tree))]))
将tree-accumulate
与此定义一起使用
> (tree-accumulate '(1 1 1 (1 (1 (1 1 1) 1 1) 1 1 (1 1 1 (1 1 1)))))
18