我正在嘗試編寫一個簡單的篩函數(shù)來計算Clojure中的素數(shù)。我已經(jīng)看到了這個關(guān)于編寫高效的篩分功能的問題,但我不是為了那點呢?,F(xiàn)在,我只是想編寫一個非常簡單(且緩慢)的篩子。這是我想出的:(defn sieve [potentials primes] (if-let [p (first potentials)] (recur (filter #(not= (mod % p) 0) potentials) (conj primes p)) primes))對于小范圍,它可以正常工作,但會導(dǎo)致大范圍的堆棧溢出: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)我以為通過使用recur它將是一個不消耗堆棧的循環(huán)結(jié)構(gòu)?我想念什么?
2 回答

www說
TA貢獻1775條經(jīng)驗 獲得超8個贊
您被filter的懶惰所打擊。更改(filter ...)為(doall (filter ...))您的recur表格,問題應(yīng)消除。
更深入的解釋:
調(diào)用會filter返回一個惰性序列,該序列將根據(jù)需要具體化已過濾序列的實際元素。如所寫,您的代碼會在...的filter基礎(chǔ)filter上堆疊filter,filter在每次迭代時再增加一層ing;在某個時候,它炸毀了。解決方案是在每次迭代時強制執(zhí)行整個結(jié)果,以便下一個迭代將對完全實現(xiàn)的seq進行過濾,并返回完全實現(xiàn)的seq,而不是添加額外的惰性seq處理層。就是doall這樣。
- 2 回答
- 0 關(guān)注
- 671 瀏覽
添加回答
舉報
0/150
提交
取消