【问题标题】:Lazy sequence min-max finder stackoverflow problem惰性序列 min-max finder stackoverflow 问题
【发布时间】:2011-04-26 18:33:31
【问题描述】:
 (defn min-max-by-columns [s]
   (reduce (fn [[smallest largest] y]
            [(map min smallest y) (map max largest y)])
      [(first s) (first s)]
      s))

我正在尝试找出一个大表(固定长度序列的序列)每一列的最大值和最小值

上面的代码适用于小表,但对于大表我得到一个堆栈溢出错误

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)

...

我是不是因为 [(first s) (first s)] 这条线而抓着头?我需要这些值才能使算法起作用。

我该如何解决这个问题?

【问题讨论】:

  • 在我看来你并没有抓住头部,但我很想知道如果你只做了一个 min 或 max 会发生什么,因此可以采取 @987654323 @ 超出等式,例如,(defn min-columns [s] (reduce (fn [x y] (map min x y)) s)).

标签: clojure lazy-evaluation


【解决方案1】:

我似乎找到了解决办法。正如 amalloy 解释的那样,(map minimum x) 和 (map max maximum 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))

【讨论】:

    【解决方案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))
    

    【讨论】:

    • 我认为你们两个正在解决不同的问题。他正在使用一个二维表并计算两个列表,一个在每列中具有最小的数字,一个在每列中具有最大的数字。 (min-max-by-columns [[1 2 9] [4 5 6] [7 8 3]]) -> [(1 2 3) (7 8 9)]。也许他只是需要在中间步骤中严格一些?
    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多