可以使用的版本,而無需創建懶序列。它的工作原理更快,更便宜:
(defn sieve* [res s]
(if (empty? s)
res
(recur (conj res (first s))
(filter #(not= 0 (mod % (first s)))
(rest s)))))
(defn sieve [n]
(sieve* [] (range 2 n)))
(sieve 10000)
=> [2 3 5 7 11 13 17 ... 9941 9949 9967 9973]
這裏是更有效的版本:
(defn sieve* [res n maxn]
(if (> n maxn)
res
(if (some #(= 0 (mod n %))
(take (round (sqrt (count res))) res))
(recur res (inc n) maxn)
(recur (conj res n) (inc n) maxn))))
(defn sieve [n]
(sieve* [] 2 n))
(last (sieve 1000000))
=> 999983
更新。相當快/便宜懶惰版本
(defn primes-seq* [primes]
(let [last-prime (last primes)]
(cons last-prime
(lazy-seq
(primes-seq*
(conj primes
(first (let [compare-primes
(take (round (sqrt (count primes)))
primes)]
(drop-while (fn [n]
(some #(= 0 (mod n %))
compare-primes))
(iterate inc (inc last-prime)))))))))))
(def primes-seq (primes-seq* [2]))
(last (take 50000 primes-seq))
=> 611953
這裏http://stackoverflow.com/questions/2980587/clojure-tail-recursive-sieve-of-eratosthenes同時要求,在這裏得到解答http://stackoverflow.com/問題/ 2946764 /遞歸函數引起-一個堆棧溢出。 –
感謝您指出這一點,這回答了我的問題,我認爲我已經充分搜索,顯然不是。 – richguy
雖然通過它後,它似乎並沒有解決我的問題。 – richguy