(defn min-max-by-columns [s]
(reduce (fn [[smallest largest] y]
[(map min smallest y) (map max largest y)])
[(first s) (first s)]
s))
我试图找出一张大表的每列的最大值和最小值(固定长度序列的序列)
上面的代码适用于小型表,但对于大型表,我得到一个stackoverflow错误
clojure.core/map/fn--3594 (core.clj:2370)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:447)
clojure.core/seq (core.clj:133)
clojure.core/map/fn--3594 (core.clj:2371)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:447)
clojure.core/seq (core.clj:133)
clojure.core/map/fn--3594 (core.clj:2371)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:447)
clojure.core/seq (core.clj:133)
clojure.core/map/fn--3594 (core.clj:2371)
...
我是否因为线[(第一个)(第一个)]而坚持到头部?我需要这些值来使算法起作用。
我该如何解决这个问题?
答案 0 :(得分:3)
我似乎找到了解决方案。正如合金所解释的那样,(映射最小的x)和(映射最大的最大x)正在同时实现。然而,我试图解决与他正在解决的问题不同的问题。幸运的是,他的洞察力帮助我找到了解决方案;诀窍是围绕每个地图包裹一个doall,以便在中间步骤中实现它们,而不是在最后一次执行时。
(defn min-max-by-columns [s]
(reduce (fn [[smallest largest] y]
[(doall (map min smallest y)) (doall (map max largest y))])
[(first s) (first s)]
s))
答案 1 :(得分:2)
(map min smallest y)
没有任何意义。您没有计算新的最小数字,而是返回[(min smallest) (min y)]
的惰性序列。最终,这些懒惰的地图堆积在彼此之上,你立即意识到它们。这很容易修复,因为你不想要开始映射任何东西!
我有点惊讶你说这对于小序列“有效”。我可以看到它没有炸毁堆栈(当然),但我不知道它是如何计算出正确答案的。无论如何,我的解决方案是
(defn min-max-by-columns [[x & xs]]
(reduce (fn [[smallest largest] x]
[(min smallest x) (max largest x)])
[x x]
xs))