- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于欧拉项目,我一直在寻找一种方法来实现埃拉托色尼筛法,因为我希望它比我最初的实现更快(并且需要它如此)。我想出了这个功能:
sieve :: Int -> [Int] -> [Int]
sieve p (x:xs) | rem x p == 0 = sieve p xs
| otherwise = x : (sieve x $ sieve p xs)
sieve _ [] = []
这行得通,但风扇速度非常快,导致堆栈溢出。我前往这里寻求建议并立即点击了spoiler对我来说,这看起来完全一样,但性能上的差异是古怪的。我仍然想继续使用我自己的实现,并且想知道是否可以轻松更改我的函数以使用更少的内存。
最佳答案
您的代码内部呈指数级增长:
sieve p (x:xs) | rem x p == 0 = sieve p xs
| otherwise = x : (sieve x $ sieve p xs)
-- ^^^^^^^ here!
-- ^^^^^^^ and here!
您打算让内部 sieve
调用继续通过 p
进行过滤,但是由于您使用相同的 sieve
函数,它也会在遇到新质数时为新质数启动新过滤器 - 但这是完全多余的,因为“上层”调用也会为相同质数启动新过滤器!
sieve 2 [3..]
= 3 : sieve 3 (sieve 2 [4..])
= 3 : sieve 3 (5 : sieve 5 (sieve 2 [6..]))
= 3 : 5 : sieve 5 (sieve 3 (sieve 5 (sieve 2 [6..])))
.... -- ^^^ ^^^ -- !!!
在 7 通过这里的四个 sieve
到达顶部后,每个都会分成两部分,创建四个新的 sieve 7
,所以链中将有八个 sieve
!!更糟糕的是,当 9 - 合成! - 通过筛子,它将 split 2、7 和 5,并且只会被 拒绝3。所以它实际上比指数级的素数 n
还差,并且接近指数级的最后一个素数产生的值(n
em>~ n log(n)
).
改成
sieve p (x:xs) | rem x p == 0 = sieve p xs
| otherwise = x : (sieve x $ filter ((>0).(`rem` p)) xs)
然后您将获得与您引用的代码等效的代码。
如果您喜欢手动编写所有代码,您可以引入一个新参数,一个控制是否启动新过滤器的 bool 标志:
primes = 2 : sieve True 2 [3..]
sieve b p (x:xs) | rem x p == 0 = sieve b p xs
| b = x : (sieve b x $ sieve False p xs)
| otherwise = x : sieve b p xs
关于performance - Prime sieve 导致(我要去)堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27289476/
这个问题在这里已经有了答案: C - determine if a number is prime (12 个答案) 关闭 4 年前。 这是 C 程序。这是我的code在下面。我用了nano在终端。
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
和17一样,是质数,反过来,71也是质数。 我们设法得到了这段代码,但我们无法完成它。 #include main() { int i = 10, j, c, sum, b, x, d, e
好像is-prime和 .is-prime区别对待他们的论点: > is-prime('11') True > '11'.is-prime No such method 'is-prime' for
我正在尝试收集有关素数的一些统计数据,其中包括数字 (prime-1)/2 的因数分布。我知道有统一选择数的因子大小的通用公式,但我还没有看到任何关于小于一个素数的因子分布的信息。 我编写了一个程序,
BigInteger的JavaDoc让我感觉很不安全,例如下面的构造函数说: BigInteger(int bitLength, int certainty, Random rnd) Construc
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我需要将蓝牙模块连接到A-Star 32U4 Prime SV microSD,但无法使其工作。作为背景,我有一个Pololu双G2大功率电机驱动器24v18盾牌Arduino连接到它。。该项目是一个
我需要将蓝牙模块连接到A-Star 32U4 Prime SV microSD,但无法使其工作。作为背景,我有一个Pololu双G2大功率电机驱动器24v18盾牌Arduino连接到它。。该项目是一个
一 构建后的图 二 实现 package graph.prim; import java.util.Scanner; public class Prim { static final in
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
我需要编写一个程序来输入一个数字并以以下形式输出其阶乘的质因数分解: 4!=(2^3)*(3^1) 5!=(2^3)*(3^1)*(5^1) 问题是我仍然不知道如何得到那个结果。 显然,括号中的每个第
我目前正在做一个项目,我需要一种有效的方法来计算素数。我使用了sieve of Eratosthenes,但是我一直在搜索,发现sieve of Atkin是一种更有效的方法。我发现很难找到对此方法的
我想找到总和为给定值的最小素数集,例如9 = 7 + 2(不是 3+3+3)。 我已经使用 sieve of eratosthens 生成了一个素数数组 我按降序遍历数组,以获得数组中小于或等于给定数
我正在学习 Real World Haskell(我在第 4 章),为了进行一些课外练习,我创建了以下程序来计算第 n 个素数。 import System.Environment isPrime p
我试图发现大数分解的复杂性。 哪一个是最佳算法,哪一个是找到数字的素因数的复杂性?假设数字的长度为n。 最佳答案 用于分解大于100个数字的整数的最知名算法是General number field
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Generating the partitions of a number Prime number sum
让我们看看我们想要找到 1 到 1000 之间的所有数字,这些数字表示为两个素数之和。例如 8 = 3+5, 24 = 13+11 现在这可以通过迭代 1 到 1000 之间的素数列表在 O(n^2)
我学会了一种叫做“线性筛”的算法https://cp-algorithms.com/algebra/prime-sieve-linear.html能够在线性时间内得到所有小于 N 的素数。 这个算法有
我正在学习 Idris,作为个人练习,我想实现一个 Primes类型,由所有素数组成。 在 idris 中是否有一种方法可以从一个类型和一个属性开始定义一个新类型,它将选择该属性为真的起始类型的所有元
我是一名优秀的程序员,十分优秀!