请在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是一个检查一个数是否为素数的函数

任何帮助都被衷心感谢。

你能提供代码的其余部分吗?

edited
当然,

(defn is_prime [num]
  (letfn [(helper [i]
       (cond
          (> i (Math/sqrt num)) true
              (= 0 (rem num i)) false
              :else (recur (inc i))))
    (helper 2)))

; 返回一个惰性序列,其中每个下一个元素都通过谓词过滤
(defn filter-lazy-seq [predicate sequence]
  (cond (= sequence  nil) nil
        (predicate (first sequence))
        (cons (first sequence) (lazy-seq (filter-lazy-seq predicate
                                                          (rest sequence))))
        :else (filter-lazy-seq predicate (rest sequence))))

(defn natural-gen []
  (letfn [(helper [n]
            (cons n (lazy-seq (helper2 (inc n)))))]
    (helper 1))
  )

(def naturals (natural-gen))

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)作为最大因子传递 -- 这,又,永远不会改变。
صورته الشخصية بواسطة
非常感谢!!!
...