我需要开发一个名为bounds的函数,它将一个嵌套的数字列表作为唯一的参数(即:一棵树)。 Bounds应该返回树中最大和最小的值。例如:
(bounds '(1 (-2 17 (4) -8 (-6 13) (-8 17))))
使用clojure而不使用flatten函数但使用递归来访问每个节点
(defn maxv [tree] (条件 (数字?树)树
(tree? tree)
(let [newmax (maxv (first tree)) ]
;;让newmax成为树中的第一个
(if(< newmax(maxv(first(rest tree))))
;;如果树中的下一个较小
(=(newmax(maxv(first(rest tree))))))
;;将newmax更改为此
(复发(maxv(休息树)))))
;;通过其余部分重复
这就是我的想法,我认为我也是java ish
答案 0 :(得分:1)
flatten
非常高效,因此自行实施没有任何好处。
如果您的嵌套列表不是太大,您可以apply
(juxt min max)
直接到展平列表:
(defn bounds [coll]
(apply (juxt min max) (flatten coll)))
对于大型输入集合,我建议使用reduce
代替apply
:
(defn bounds [coll]
(reduce (fn [[minv maxv :as res] v]
(if res [(min minv v) (max maxv v)] [v v]))
nil
(flatten coll)))
如果你真的需要纯粹的递归实现,这里有一个例子:
(defn bounds [coll]
(loop [coll coll [minv maxv :as res] nil]
(if-let [[h & ts] (seq coll)]
(if (sequential? h)
(recur (concat h ts) res)
(recur ts (if res [(min minv h) (max maxv h)] [h h])))
res)))
所有三个实现都会产生一个包含最小值和最大值的元组:
(bounds '(1 (-2 17 (4) -8 (-6 13) (-8 17)))) ; => [-8 17]
sum-tree
来自评论的实施在您的代码中使用multiple recursion是一个非常糟糕的主意,因为它会非常快速地炸掉您的堆栈:
(sum-tree (range 7000)) ; => java.lang.StackOverflowError
尝试使用tail recursion与recur或higher-order functions代替:
(defn sum-tree [tree]
(if (number? tree)
tree
(reduce + (map sum-tree tree))))