我在下面参加了一个项目欧拉编码挑战赛,该代码给出的答案是正确的,但是我不明白为什么要花近一分钟的时间来运行它。在使用筛子之前,它以相似的时间完成。其他用户报告的时间低至毫秒。

我认为我在某个地方犯了一个基本错误...

   // The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
   // Find the sum of all the primes below two million.
   public static long Ex010()
   {
      var sum = 0L;
      var sieve = new bool[2000000];
      var primes = new List<int>(10000);

      for (int i = 2; i < sieve.Length; i++)
      {
         if (sieve[i-1])
            continue;

         var isPrime = true;
         foreach (var prime in primes)
         {
            if (i % prime == 0) {
               isPrime = false;
               break;
            }
         }

         if (isPrime) {
            primes.Add(i);
            sum += i;

            for (var x = i * 2; x < sieve.Length; x += i) {
                  sieve[x-1] = true;
            }
         }
      }

      return sum;
   }


编辑:

唯一似乎缺少的是此优化:

        if (prime > Math.Sqrt(i))
            break;


它将时间缩短到160毫秒。

编辑2:

最后单击,多次提出建议。现在是12毫秒。最终解决方案:

   public static long Ex010()
   {
      var sum = 0L;
      var sieve = new bool[2000000];

      for (int i = 2; i < sieve.Length; i++)
      {
         if (sieve[i-1])
            continue;

         sum += i;

         for (var x = i * 2; x < sieve.Length; x += i) {
            sieve[x-1] = true;
         }
      }

      return sum;
   }

最佳答案

除了筛子,您还需要进行试验划分。
布尔数组将已经告诉您一个数字是否为质数,因此您根本不需要质数表。
您也可以通过仅筛选极限的平方根来加快速度。
如果还想节省一些内存,则可以使用BitArray而不是布尔数组。

public static long Ex010()
{
    const int Limit = 2000000;
    int sqrt = (int)Math.Sqrt(Limit);
    var sum = 0L;
    var isComposite = new bool[Limit];

    for (int i = 2; i < sqrt; i++) {
        if (isComposite[i - 2])
            continue;//This number is not prime, skip

        sum += i;

        for (var x = i * i; x < isComposite.Length; x += i) {
            isComposite[x - 2] = true;
        }
    }
    //Add the remaining prime numbers
    for (int i = sqrt; i < Limit; i++) {
        if (!isComposite[i - 2]) {
            sum += i;
        }
    }
    return sum;
}

关于c# - 使用筛子后质数求和仍然很慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37441056/

10-13 01:07