种植我的Clojure树
我希望有人能帮上忙,所以我从面向对象编程跳到函数式编程,这有点让人望而生畏!我试图编写一个函数,它将返回子树中的数字总和,但我只想返回子树中的较大值。这有意义吗?我已经写了一个函数,它返回总树的最大和,但是想要扩展 例如:种植我的Clojure树,clojure,functional-programming,lisp,Clojure,Functional Programming,Lisp,我希望有人能帮上忙,所以我从面向对象编程跳到函数式编程,这有点让人望而生畏!我试图编写一个函数,它将返回子树中的数字总和,但我只想返回子树中的较大值。这有意义吗?我已经写了一个函数,它返回总树的最大和,但是想要扩展 例如: [] | --------- | | [] [] / \ /\ 1 [] 3 [] <--biggest sub-tree /\
[]
|
---------
| |
[] []
/ \ /\
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
))
但我无法在我当前的函数中实现这一点,我完全无法扩展它。有人能帮忙吗?树上的递归函数总是有点麻烦,特别是当您试图在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?
我只是假设任何不是集合的东西都是一个数字-如果你有一个更混合的数据树,你应该能够通过用cond
替换外部的if
和一个最后的:else 0
子句来处理它,就像你的尝试一样
这里的主要补充是在决定如何处理内部节点之前查看它们的子节点。如果它们都是数字,那么我们就是在求和。如果不是,那么我们完全是一个内部节点,需要取
max
。您可以使用apply
(基本上,(apply f[x y z])
是(f x y z)
-它将集合作为单个参数插入函数中),一旦我们使用map
递归地获得子树子节点的max子树和
s。您能再次解释一下,对于非叶节点,您想做什么吗?你想为每个子树添加所有数字,然后取最大值吗?对不起,我应该更新我的图表。对于不是叶子的节点,我可以忽略它们。但是是的,我想对所有的子树取所有的数字,只返回最大值最高的子树的总数。我想你的问题可能是你对子树的定义不够清晰。例如,可以定义深度值,只考虑低于该深度的子树。这将使修改您所做的事情变得相当容易,因为您只能从该深度开始递归添加。或者,您可以将感兴趣的子树定义为叶节点上方的级别。所有这一切都取决于你需要的是“最大的子树”是指具有最大子节点和的节点,条件是它的所有子节点都必须是叶子?
(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