相关疑难解决方法(0)

递归函数导致堆栈溢出

我正在尝试编写一个简单的筛子函数来计算clojure中的素数.我已经看到了这个关于编写高效的筛分功能的问题,但我不是为了那点呢.现在我只想写一个非常简单(缓慢)的筛子.以下是我的想法:

(defn sieve [potentials primes]
  (if-let [p (first potentials)]
    (recur (filter #(not= (mod % p) 0) potentials) (conj primes p))
    primes))
Run Code Online (Sandbox Code Playgroud)

对于小范围,它工作正常,但导致堆栈溢出大范围:

user=> (sieve (range 2 30) [])
[2 3 5 7 11 13 17 19 23 29]
user=> (sieve (range 2 15000) [])
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)

我认为通过使用recur这将是一个非堆栈消耗循环结构?我错过了什么?

recursion primes clojure lazy-evaluation lazy-sequences

38
推荐指数
1
解决办法
2161
查看次数

Clojure - Eratosthenes的尾递归筛

我在Clojure中实现了Eratosthenes的筛子:

(defn sieve [n]
  (loop [last-tried 2 sift (range 2 (inc n))]
    (if
      (or (nil? last-tried) (> last-tried n))
      sift
      (let [filtered (filter #(or (= % last-tried) (< 0 (rem % last-tried))) sift)]
        (let [next-to-try (first (filter #(> % last-tried) filtered))]
        (recur next-to-try filtered))))))
Run Code Online (Sandbox Code Playgroud)

对于较大的n(如20000),它以堆栈溢出结束.为什么尾部呼叫消除不在这里工作?怎么解决?

algorithm primes functional-programming clojure sieve-of-eratosthenes

9
推荐指数
1
解决办法
1397
查看次数

在clojure连锁电话?

我正试图在Clojure中实施Eratosthenes的筛子.我想测试的一种方法是:

  1. 获得范围(2 3 4 5 6 ... N)
  2. 对于2 <= i<= N.
    • 通过我的范围filter,删除倍数i
    • 对于i+1迭代,使用先前过滤的结果

我知道我可以用它loop/recur,但这会导致堆栈溢出错误(由于某种原因,不应用尾调用优化).

我怎么能迭代地做呢?我的意思是调用N次调用相同的例程,将i迭代的结果传递给i+1th.

algorithm functional-programming clojure

4
推荐指数
1
解决办法
495
查看次数