我正在开始我的欧拉计划探险。和其他许多我已经想到的一样,我需要制作一个质数生成器。问题是:PHP不喜欢大数字。如果我使用标准的Sieve of Eratosthenes function,并将限制设置为200万,它将崩溃。它不喜欢创建该大小的数组。可以理解的

所以现在我正在尝试对其进行优化。我发现,一种方法是创建一个带有200万个变量的数组,而不是只需要100万个(只有奇数可以是质数)。但是现在它崩溃了,因为它超过了最大执行时间...

function getPrimes($limit) {
$count = 0;
for ($i = 3; $i < $limit; $i += 2) {
    $primes[$count++] = $i;
}

for ($n = 3; $n < $limit; $n += 2) {
    //array will be half the size of $limit
    for ($i = 1; $i < $limit/2; $i++) {
        if ($primes[$i] % $n === 0 && $primes[$i] !== $n) {
            $primes[$i] = 0;
        }
    }
}

return $primes;
}


该功能有效,但是正如我所说,它有点慢...有什么建议吗?

我发现可以更快一点的是切换循环。

foreach ($primes as $value) {
    //$limitSq is the sqrt of the limit, as that is as high as I have to go
    for ($n = 3; $n = $limitSq; $n += 2) {
        if ($value !== $n && $value % $n === 0) {
            $primes[$count] = 0;
            $n = $limitSq; //breaking the inner loop
        }
    }
    $count++;
}


除了设置时间和内存限制(感谢Greg),我终于设法得到了答案。 je

最佳答案

来自Algorithmist's proposed solution


这是对标准的修改
Eratosthenes筛。这将是
效率很低,也用光了很多
大量的内存和时间来运行
标准筛一直到n。
但是,不小于
等于n将有一个因数
大于sqrt {n},
所以我们只需要知道所有的素数
到这个极限,不大于
比31622(10 ^ 9的平方根)。这个
用筛子完成。然后,
对于每个查询,我们仅筛选
给定的范围,使用我们的
预先计算的素数表
消除复合数字。


这个问题也出现在UVA和Sphere的在线评审中。 Here's how it's enunciated on Sphere.

10-08 02:04