我想知道是否有人可以帮助我,因为我已经使用此代码打了一个块。我的代码如下所示。
当我运行跟踪时,它会在达到零值时一直停止,是否有人知道出了什么问题?
这是我的数据:
'(1 ( -2 17 (4)) -8 (6 13)))
代码:
(defn tree? [t]
(and (seq t) (not (empty? t))))
(defn bounds2
([tree] (bounds2 tree 99 -99))
([tree minVal maxVal]
(cond
(number? tree) tree
(tree? tree)
(cond
(nil? (bounds2 (first tree) minVal maxVal))
(bounds2 (rest tree) minVal maxVal)
((complement nil?) (bounds2 (first tree) minVal maxVal))
(cond
(< (bounds2 (first tree) minVal maxVal) minVal)
(recur (rest tree) (first tree) maxVal)
(> (bounds2 (first tree) minVal maxVal) maxVal)
(recur (rest tree) minVal (first tree)))
(empty? tree) nil))))
答案 0 :(得分:0)
这里有几个问题。最直接的一个是你永远不会实际返回任何界限。 cond
语句中的每个可能的退出点都是各种未修改的递归调用,数字或nil
。从逻辑上讲,您需要在某些时候返回类似[minVal maxVal]
的内容,并且您应该期望所有递归调用都返回该格式的内容。当然,这会使你的比较逻辑变得相当复杂。
其他重要的一点包括tree?
在逻辑上等同于seq
(正如评论中指出的那样),而你的(empty? tree)
子句是死代码,因为{{1}绝不能同时满足tree
= tree?
和seq
。 (事实证明,empty?
仍会返回(bounds2 '())
,但这是因为nil
如果您没有匹配任何子句就会返回cond
。)
如果您原谅完全重写,我认为这可以满足您的需求,与原始代码完全相同。 (您在评论中提到您不想使用nil
,因此我避免使用它和中间flatten
解决方案。)
reduce
我的大多数变化都是文体的(使用(defn bounds2 [tree]
(loop [[x & more :as tree] tree, minVal 99, maxVal -99]
(cond
(empty? tree) [minVal maxVal]
(number? x) (recur more (min x minVal) (max x maxVal))
(seq x) (recur (concat x more) minVal maxVal))))
而不是多个arities;解构;取消嵌套loop
语句);这里逻辑的一个主要变化是我们正在使用cond
到“concat
”。同样重要的是要注意,对我们的所有递归调用使用flatten
将有助于保护我们免于破坏堆栈。