如何使用apply in scheme编写树形图函数

时间:2016-02-09 12:13:54

标签: tree scheme racket

写完后

(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)) 适用于仍在工作?

2 个答案:

答案 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,类似于foldrfoldl。所以无论如何,这是使用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