的尾遞歸篩餘有此實現埃拉託塞尼的Clojure中篩的:的Clojure - 埃拉託塞尼
(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))))))
對於較大n
(如20000)將其與堆棧溢出結束。爲什麼不在這裏尾呼消除工作?如何解決它?
作爲一個附註,但這不是Eratosthenes的篩子。 SoE不執行剩餘操作,只是添加和「交叉」。參見http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf進行擴展討論(這是一篇很棒的閱讀!);對於Christophe Grand在Clojure中一個漂亮的「增量」SoE實現,請參閱http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/(它也是最快的迄今爲止我見過的版本)。 – 2010-06-05 14:18:29
@MichałMarczyk謝謝。我會說「交叉」等同於「過濾」,並且此算法中的「加法」相當於「乘法」,因此也就是「餘數」。 – 2010-06-05 14:32:18
不是。結果當然是一樣的,但算法的複雜性是非常不同的。 – 2010-06-05 14:33:21