成长我的Clojure树

时间:2015-11-14 13:01:20

标签: clojure functional-programming lisp

我希望有人可以提供帮助,所以我正在从OOP跃升到功能编程,这有点令人生畏!我正在尝试编写一个函数,它将返回子树中数字的总和,但我只想返回更大值的子树。如果这有道理?我编写了一个函数,它返回总树数maxsum但想要扩展

例如:

         []
         |
    ---------
    |        |
    []      []    
   / \      /\
  1   []   3  []    <--biggest sub-tree
      /\      /\
     3  2    8  8

(defn is-tree [tr]
  (and (seq? tr) (not (empty? tr))))

(defn tree-total [tree]
  (cond
    (number? tree) tree

    (is-tree tree)
    (+ (tree-total (first tree))
      (tree-total (rest tree)))

    :else 0
    ))

就我而言,这给了我一整件事,但我无法实现它只在子树上进行数学计算......任何人都可以帮助我吗?

我有一个解决方案,但它没有让我在任何地方,这是...

(let [l-s-tree (myhelperfunc? (first tree))
      r-s-tree (myhelperfunc? (last tree))

      lt (tree-sum (first tree))
      rt (tree-sum (last tree))

      both (+ lt rt)]

但是我无法将其实现到我当前的功能中,我完全不知道如何扩展它。任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

树上的递归函数总是有点麻烦,特别是当你试图在REPL上测试它们时。这是我的尝试:

(defn max-subtree-sum [x]
  (if (coll? x) ;;Is this an internal node?
    (if (every? number? x) 
      ;;If every child is a number, we should sum them.
      (apply + x)
      ;;otherwise recur once for each child and take the max
      (apply max (map max-subtree-sum x)))
     x))

(max-subtree-sum [[1 [3 2]] [3 [8 8]]])
;; => 16
(max-subtree-sum '((1 (3 24)) (3 (8 8))));; Or with lists
;; => 27

我使用coll?检查树状图,因为在你的图表中看起来你的内部节点是向量,而事实证明那些不是seq?我只是假设任何东西不是集合是一个数字 - 如果你有一个更混合的数据树,你应该能够通过用if和最后的cond子句替换外部:else 0来处理它喜欢你的尝试。

这里的主要补充是在决定如何处理它们之前查看内部节点的子节点。如果他们都是数字,那么我们就是在赚钱。如果他们不是,那么我们就是一个完全内部的节点,需要取代max。您可以使用apply执行这两项操作(基本上,(apply f [x y z])(f x y z) - 它会将集合作为单个参数传递到函数中),一旦我们使用map递归获取{ {1}}子树的子项。