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
              :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)`作为最大因子传递——同样,这个值也不会改变。
非常感谢!!!
...