简体   繁体   English

求素数和的更有效方法是什么?

[英]What's a more efficient way to find sum of prime numbers?

I am working on a program that tracks the amount of time it takes to get the sum of all prime numbers up to a certain number and am trying to find the most efficient possible way to obtain this value, as I have a Stopwatch (System.Diagnostics) tracking how long it takes.我正在开发一个程序,该程序跟踪将所有质数的总和达到某个数字所需的时间,并试图找到获得该值的最有效方法,因为我有一个秒表 (System.诊断)跟踪需要多长时间。 Currently, I can find the sum of all prime numbers up to 40,000 in about 33-34 seconds with the below code:目前,我可以使用以下代码在大约 33-34 秒内找到最多 40,000 的所有质数的总和:

private void ListThePrimes()
        {
            prime = false;
            while (primes < 30000)
            {
                for (int i = 2; i < n; i++)
                {

                    output = n % i;
                    if (output == 0)
                    {
                        primeNum = i;
                        prime = false;
                        break;
                    }
                    else
                    {
                        prime = true;
                    }
                }
                if (prime == true)
                {
                    sum += primeNum;
                    primes++;
                }
                n++;
            }
        }

However, I feel like there is a way to write this code more efficiently as my goal was to reach the same amount of time with much higher numbers like 200,000 or so.但是,我觉得有一种方法可以更有效地编写此代码,因为我的目标是用更高的数字(如 200,000 左右)达到相同的时间。 This is my Stopwatch code, which I perform on a button click, if needed:这是我的秒表代码,如果需要,我会在单击按钮时执行该代码:

    var timer = new Stopwatch();
            timer.Start();
            ListThePrimes();
            timer.Stop();
            TimeSpan timeTaken = timer.Elapsed;
            string foo = timeTaken.ToString(@"m\:ss\.fff");
            MessageBox.Show("The sum is " + sum + ". It took this program " + foo + " seconds to run.");

Would appreciate it if someone could let me know if there is a more efficient way to perform this action.如果有人能让我知道是否有更有效的方法来执行此操作,我将不胜感激。

You need to optimize how you get prime numbers, your way is extremely inefficient.您需要优化获得质数的方式,您的方式非常低效。 The common way to do so is using the Sieve of Eratosthenes .这样做的常用方法是使用Eratosthenes 筛 Using this method I can easily get all prime numbers up to 100000 in milliseconds.使用这种方法,我可以在几毫秒内轻松获得最多 100000 的所有质数。 Summing them is trivial beyond that.除此之外,总结它们是微不足道的。

var n = 100000;
var a = Enumerable.Range(0,n+1).Select(_ => true).ToArray();

for(var i=2;i<Math.Sqrt(n);i++)
{
    if(a[i])
    {
        for(var j = i*i;j<=n;j += i)
        {
            a[j] = false;
        }
    }
}

var result = a.Select( (x,i) => new {IsPrime = x,Prime = i})  
              .Where(x => x.IsPrime && x.Prime > 1) 
              .Sum(x => x.Prime);
    
Console.WriteLine(result);

Live example: https://dotnetfiddle.net/eBelZD现场示例: https : //dotnetfiddle.net/eBelZD

You really have to work on your prime number method.你真的必须研究你的素数方法。 A new approach would be the Erathostenes sieve, but your current code can also be improved quite a bit.一种新方法是 Erathostenes 筛法,但您当前的代码也可以改进很多。

  1. Remove unnecessary variables like output, just put it directly in the if tag.去掉输出等不必要的变量,直接放在if标签中即可。
  2. You can half the numbers you're checking because primes can only be odd numbers, so don't do n++ but n+=2;.您可以将要检查的数字减半,因为素数只能是奇数,所以不要使用 n++ 而是 n+=2;。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM