【发布时间】:2017-02-23 14:17:14
【问题描述】:
如何优化算法的速度/效率?
我需要计算 1 到 10^15 范围内的素数总数。
编辑:约束:last-first<=10^9
下面的代码适用于较小的范围(从 1 到 2000000)并且需要 4 秒(几乎)。
static void Main(string[] args)
{
string[] s = Console.ReadLine().Split(' ');
DateTime start = DateTime.Now;
var first = Convert.ToInt64(s[0]);
var last = Convert.ToInt64(s[1]);
int counter = 0;
for (long i = first; i <= last; i++)
{
if (i > 2 && i%2==0)
{
continue;
}
if (isPrime(i))
{
counter++;
}
}
Console.WriteLine(counter);
TimeSpan duration = DateTime.Now - start;
Console.WriteLine(duration.TotalMilliseconds);
Console.ReadLine();
}
public static bool isPrime(long number)
{
if (number == 1) return false;
if (number == 2) return true;
for (int i = 2; i <= Math.Ceiling(Math.Sqrt(number)); ++i)
{
if (number % i == 0) return false;
}
return true;
}
正如您在for loop 中看到的,首先我检查数字是否为i > 2 && i%2==0,因为在这种情况下,数字不是素数。
还有什么技巧可以避免这些数字无法到达isPrime 方法,或者避免超时的最佳解决方案是什么?注意:此代码有效,但问题是我需要避免超时,即 4 秒。
【问题讨论】:
-
Prime Number Formula的可能重复
-
你可以通过只检查奇数的素数来稍微减少时间。
-
@MatthewWatson 我在 for 循环中使用 i%2==0 做到了这一点
-
@gagro - 是的,但是 inside
isPrime你检查number与 everyi每 oddi. -
github.com/kimwalisch/primecount 包含几种不同的素数计数算法,可以在 4 秒的时间限制内解决您的问题。 10^15 大到足以让简单的方法变得太慢。