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 自然数生成器 []
  (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)作为max-factor传递--这同样永远不会改变。
非常感谢!!!
...