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]
  (当 seq  = nil 时) nil
        (pred (first seq))
        (cons (first seq) (lazy-seq (filter-lazy-seq pred
                                                          (rest seq)))))
        :else (filter-lazy-seq pred (rest seq))))

(defn 自然数的生成 []
  (letfn [(辅助 [n]
            (cons n (lazy-seq (辅助2 (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)作为最大因子传递——同样,它永远不会改变。
非常感谢!!!
...