我希望有人可以提供帮助,所以我正在从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)]
但是我无法将其实现到我当前的功能中,我完全不知道如何扩展它。任何人都可以帮忙吗?
答案 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}}子树的子项。