Haskell中素数的生成
在过去的几天里,我一直在学习Haskell,通过向您学习Haskell。我一直在尝试完成一些项目Euler问题,其中一些需要素数。然而,我编写的函数试图生成一些(在本例中,素数低于20000)输出不正确。当我运行它时,Haskell中素数的生成,haskell,primes,Haskell,Primes,在过去的几天里,我一直在学习Haskell,通过向您学习Haskell。我一直在尝试完成一些项目Euler问题,其中一些需要素数。然而,我编写的函数试图生成一些(在本例中,素数低于20000)输出不正确。当我运行它时,GHCi返回'[1',,并且似乎没有终止。我使用的代码是: sieve :: (Integral a) => a -> [a] -> [a] sieve 20000 list = list sieve n (x:xs) = sieve (n+1) $ x:(fil
GHCi
返回'[1',,并且似乎没有终止。我使用的代码是:
sieve :: (Integral a) => a -> [a] -> [a]
sieve 20000 list = list
sieve n (x:xs) = sieve (n+1) $ x:(filter (\q -> q `mod` n /= 0) xs)
primesto20000 = sieve 2 [1..20000]
然后我打电话给
primesto20000
。我知道这个函数可能效率低下,我主要是就我一定犯过的语法/过程错误寻求帮助。谢谢你你过滤掉了每个数字的倍数,而不仅仅是质数。你想用
x
而不是n
来检查整除性。(事实上,我不确定你是否需要sieve
函数中的n
;只要让你的primesto20000
函数生成适当的输入列表,并传递它即可。)你过滤掉的是每个数字的倍数,而不仅仅是质数。你想用x
而不是n
来检查可除性。(事实上,我不确定您是否需要sieve
函数中的n
;只需让您的primesto20000
函数生成适当的输入列表,然后传递即可。)您的代码中有两个问题:
- 因为它的时间复杂性(我猜是二次的),它不能在合理的时间内完成,而且它似乎只是挂起。如果用200替换20000,它将完成,但结果将是
[1]
- 另一个问题是,对于每个
,您希望过滤所有可被n
整除且大于n
的数字。如果没有此条件,您将过滤n
本身,结果是过滤掉所有数字n
limit::积分a=>a
限额=20000
筛::(积分a)=>a->[a]->[a]
筛n列表| n==极限
=列表
筛n(x:xs)
=筛子(n+1)$x:(过滤器过滤器xs)
哪里
--过滤所有可被'n'整除的内容,但不过滤'n'本身。
filt q=(q代码中有两个问题:
- 因为它的时间复杂性(我猜是二次的),它不能在合理的时间内完成,而且它似乎只是挂起。如果用200替换20000,它将完成,但结果将是
[1]
- 另一个问题是,对于每个
n
,您希望过滤所有可被n
整除且大于n
的数字。如果没有此条件,您将过滤n
本身,结果是过滤掉所有数字
更正后的版本可能如下所示(具有参数化限制):
limit::积分a=>a
限额=20000
筛::(积分a)=>a->[a]->[a]
筛n列表| n==极限
=列表
筛n(x:xs)
=筛子(n+1)$x:(过滤器过滤器xs)
哪里
--过滤所有可被'n'整除的内容,但不过滤'n'本身。
filt q=(q我不确定为什么这个函数似乎没有终止,但我可以理解为什么它只输出1,不是因为你过滤掉了素数及其导数吗?我打算附加素数(即列表中的第一个数字)使用过滤函数之前的x:x,它只作用于列表的其余部分,xs。我该怎么做?@kimitsudesa作为旁注,这不是一个筛子。它只是一个试除法素数生成器。顺便说一句,你可能想检查一下你是否关心后面的性能。你使用的算法比试除法更糟糕。我不确定为什么这个函数似乎没有终止,但我可以理解为什么它只输出1,不是因为你过滤掉了素数及其导数吗?我打算附加素数(即列表中的第一个数字)使用过滤函数之前的x:x,它只作用于列表的其余部分,xs。我该怎么做?@kimitsudesa作为旁注,这不是一个筛子。它只是一个试除法素数生成器。顺便说一句,你可能想检查你是否关心后面的性能。你使用的算法比试除法更糟糕。我刚刚试过使用qmod
x,它导致函数终止,但只返回[1]尝试将列表[2..20000]
作为输入传递给它。我认为第一步是过滤掉所有内容。我只是尝试使用qmod
x,它导致函数终止,但只返回[1]尝试传递列表[2..20000]
作为输入。我认为第一步是过滤掉所有内容。谢谢,看到Haskell代码的好例子非常有帮助谢谢,看到Haskell代码的好例子非常有帮助
limit :: Integral a => a
limit = 20000
sieve :: (Integral a) => a -> [a] -> [a]
sieve n list | n == limit
= list
sieve n (x:xs)
= sieve (n+1) $ x : (filter filt xs)
where
-- filter everything divisible by `n`, but not `n` itself.
filt q = (q <= n) || (q `mod` n /= 0)
primesto20000 = sieve 2 [1..limit]