Sieve of Eratosthenes 的 Haskell/Scheme 实现
Sieve of Eratosthenes 算法描述见 http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Haskell 实现如下:
- sieve :: [Integer] -> [Integer]
- sieve (x:xs) = x : sieve xs'
- where xs' = filter (y -> y `mod` x /= 0) xs
- primes = 2 : sieve [3,5..]
复制代码
加了平方优化后的版本
- sieve :: [Integer] -> [Integer]
- sieve (x:xs) = x : sieve (xs' ++ xs''')
- where
- (xs', xs'') = break (>= x*x) xs
- xs''' = filter (y -> y `mod` x /= 0) xs''
- primes = 2 : sieve [3,5..]
复制代码
实际上,第二个版本有严重的性能问题(break 会导致大量的内存操作)以至于还没有第一个快。
真正优化的版本(by win_hate):
- isPrime :: Integer -> [Integer] -> Bool
- isPrime p (x:xs)
- | x*x > p = True
- | p `mod` x == 0 = False
- | otherwise = isPrime p xs
- primes = 2 : [ p | p <- [3,5..], isPrime p primes ]
复制代码
BTW,这个还可以再稍加优化。
[ 本帖最后由 MMMIX 于 2009-5-20 14:15 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
估计是版本的问题,我看你用的还是 3.72, 我测试时用的是 4.1
collects/lazy/lang/reader.ss 这个文件在我这是有的,内容很简单:
复制代码
[ 本帖最后由 MMMIX 于 2008-9-21 18:31 编辑 ]
我不是很明白你的意思。
如果直接选 lazy scheme,是可以运行的。我回的第一贴用的就是这个环境
drs01.png (30.2 KB, 下载次数: 28)
下载附件
2008-09-21 17:48 上传
如果把语言选为 module,则得到一条错误。
drs02.png (33.41 KB, 下载次数: 26)
下载附件
2008-09-21 17:44 上传
可能我模块那里没写对?
[ 本帖最后由 win_hate 于 2008-9-21 17:49 编辑 ]
其实用 #lang 也是可以的,不过直接用 (list-ref primes 50) 是没有输出的,但是可以用 (display (list-ref primes 50)) 显示结果。
谢谢!
用模块之后可以了,但对整个体系还是很模糊。要找个时间把 PLT 的文档好好看一看才行。
复制代码
mzscheme 不清楚(应该也行),我向来都是直接用 DrScheme 的
在 DrScheme 中应该把语言设为 Module,然后通过 #lang 选择具体要用的语言,这也是推荐的作法。
说得对,用奇数列相当于在选材上先 filter 了一次。
那个 #lang lazy 在 mzscheme 中好用吗?我这里试了不行。
[ 本帖最后由 win_hate 于 2008-9-21 10:34 编辑 ]
一个带平方优化的版本
复制代码
我觉着 integers 的定义可以优化下
PLT Scheme 实现(需要在 DrScheme 中将语言设为 Module)
复制代码
复制代码
[ 本帖最后由 MMMIX 于 2008-9-21 10:51 编辑 ]
lazy scheme
复制代码