Clojure中链打电话? [英] Chain call in clojure?

查看:128
本文介绍了Clojure中链打电话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现的Clojure筛埃拉托色尼的。一种方法我想测试是这样的:

  1. 在获取范围(1 2 3 4 5 6 ... N)
  2. 对于2'= < = N
    • 过滤器,消除的乘法通过我的范围我
    • I + 1 次迭代,previous过滤的使用效果

我知道我可以用环/复发做到这一点,但是这是导致堆栈溢出错误(由于某种原因,尾部调用优化不适用)。

我如何能做到反复?我的意思是调用n次的调用同一个程序,通过的结果,我次迭代 I + 1 日。

解决方案

 (defn筛[求末页]
  (letfn [(​​西瑞尔[到筛]
                  (如果(空?来筛),筛分
                  (让[F&安培; R],以筛]
                    (如果(大于F(数学/开方端))(成过筛筛)
                        (复发(删除#(零?(MOD%F))R)
                           (连词过筛F))))))]
    (西瑞尔(范围BEG(INC结束))[])))
 

这一次似乎工作得很好。以测试它(筛2 1000000),并返回秒内没有吹。

I'm trying to implement sieve of Eratosthenes in Clojure. One approach I would like to test is this:

  1. Get range (2 3 4 5 6 ... N)
  2. For 2 <= i <= N
    • Pass my range through filter that removes multiplies of i
    • For i+1th iteration, use result of the previous filtering

I know I could do it with loop/recur, but this is causing stack overflow errors (for some reason tail call optimization is not applied).

How can I do it iteratively? I mean invoking N calls to the same routine, passing result of ith iteration to i+1th.

解决方案

(defn sieve [beg end]
  (letfn [(siever [to-sieve sieved]
                  (if (empty? to-sieve) sieved
                  (let [[f & r] to-sieve]
                    (if (> f (Math/sqrt end)) (into sieved to-sieve)
                        (recur (remove #(zero? (mod % f)) r) 
                           (conj sieved f))))))]
    (siever (range beg (inc end)) [])))

This one seems to work just fine. Tested it with (sieve 2 1000000) and returns within seconds without blowing.

这篇关于Clojure中链打电话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆