如何进一步优化Eratosthenes的筛选

时间:2017-12-14 22:45:20

标签: c# optimization primes sieve-of-eratosthenes

我正在解决Project Euler问题10,并且我能够使用Eratosthenes的Sieve来实现,但现在我想进一步优化代码。

考虑到大于3的所有素数都是6k+16k-1形式的事实我只在数组中将这些值设置为true,但并不是该形式的所有数字都是素数,所以我必须筛选值并删除非素数,我的代码如下:

public static bool[] GeneratePrimes(int bound)
    {
        bool[] isPrime = new bool[bound];
        isPrime[2] = true;
        isPrime[3] = true;

        // Taking into account that all primes greater than 2 and 3
        // Are of the form 6k+1 or 6k-1

        for (int k = 6; k < isPrime.Length; k += 6)
        {
            if (k + 1 < isPrime.Length) isPrime[k + 1] = true;
            isPrime[k - 1] = true;
        }

        // At this point we still have some numbers that aren't prime marked as prime
        // So we go over them with a sieve, also we can start at 3 for obvious reasons

        for (int i = 3; i * i <= bound; i += 2)
        {
            if (isPrime[i])
            {
                // Can this be optimized?
                for (int j = i; j * i <= bound; j++)
                    isPrime[i * j] = false;
            }
        }

        return isPrime;
    }
}

那么如何通过减少数量来优化我筛选的代码呢?例如,如果我的数字是5,那么10,15,20之类的数字已经被触发,但是25例如不是这样可能只能通过25这样的值?

2 个答案:

答案 0 :(得分:2)

保罗·普里查德(Paul Pritchard)与轮筛做了很多工作,将你的6k±1想法扩展到更大的主轮。谷歌“pritchard轮筛”或看my blog开始。

答案 1 :(得分:1)

当消除素数p的倍数时,您只需要从p * p开始。由于它具有较小的素因子,因此已经消除了任何低于p的倍数。这就是你对5和25的评论背后的原因。