2024 Clojure状态调查中分享您的想法!

欢迎!有关此工作方式的更多信息,请参阅关于页面。

0
序列

你好,我是Clojure和延迟序列的新手。

(defn get-biggest-prime-factor [num]
  (let [max-check (inc (Math/sqrt num))
        lazy-primes (filter-lazy-seq is_prime naturals)]
    (loop [prime (first lazy-primes)
           max-factor 1]
      (cond (>= prime max-check) max-factor
            (= 0 (rem num prime)) (recur (first (rest lazy-primes)) (first lazy-primes))
            :else (recur (first (rest lazy-primes)) max-factor)))) )
  • naturals 是一个包含1, 2, 3 ... 的无限延迟序列,
  • filter-lazy-seq 是一个函数,它返回由第二个参数推导出的延迟序列。序列的每个元素都经过第一个参数的验证,该参数是一个谓词
  • is-prime 是一个检查一个数是否为素数的函数

欢迎任何帮助。

你能提供其余的代码吗?

编辑
当然,

(defn is_prime [num]
  (letfn [(helper [i]
            (cond
              (> i (Math/sqrt num)) true
              (:= 0 (rem num i)) false
              否则 ( recur (inc i))))]
    (辅助函数 2)))

返回一个惰性序列,每个后续元素都经过谓词过滤
(defn 惰性序列过滤 [谓词 序列]
  (cond (= 序列  nil) nil
        (谓词 (first 序列))
        (cons (first 序列) (lazy-seq (惰性序列过滤 谓词
                                                          (rest 序列))))
        否则 (惰性序列过滤 谓词 (rest 序列))))

(defn 自然数生成 []
  (letfn [(辅助函数 [n]
            (cons n (lazy-seq (辅助函数 (inc n)))))]
    (辅助函数 1))
  )

(def 自然数 (自然数生成))

1 个回答

+1

选择
 
最佳回答

我认为你的问题是“保留头部” -- 你的函数将lazy-primes 绑定到序列,然后你遍历序列,所以你仍然对这个整个序列有引用,如果你请求足够大的num,你会超出堆的大小,因为你的函数需要整个序列来工作。

所以,即使我请求很小的数字(即(get-biggest-prime-factor 6)),评估也会继续直到内存溢出。我在问题的评论部分提供了其余的代码。
现在我看到所有代码并在REPL中尝试了,我能看到问题

在`get-biggest-prime-factor`函数中,当你递归时,你传递`(first (rest lazy-primes))`,但是`lazy-primes`在循环中不会改变,所以你总是传递2,它反复检查相同的值。

此外,在一次递归调用中,你将`(first lazy-primes)`作为`max-factor`传递--这同样永远不会改变。
非常感谢!!
...