我正在尝试使用javascript从http://projecteuler.net解决数学问题:找到低于200万的所有素数之和。当我运行我写的脚本时,我的浏览器崩溃了(我正在使用谷歌浏览器)。这是脚本:
function isPrime(num)
{
if(num < 2)
return false;
for (var i = 2; i < num; i++)
{
if(num%i==0)
return false;
}
return true;
}
var total=0e1;
for (var i = 1; i < 2000000; i++)
{
if(isPrime(i))
{
total=total+i;
}
}
document.write("The sum of all the primes below two million is ",total);
该脚本适用于较小的数字(i <100000)。这有什么问题?我该如何解决?谢谢你的帮助。
答案 0 :(得分:1)
函数isPrime
为您检查的每个 n 执行 n 模运算(因为您检查每个小于素数的数字作为因子)。假设about one in every seven numbers is prime,表示您在代码段中执行isPrime
函数约28,000次,并且您正在执行the modulo operation about 392 million times。可能,Chrome正在崩溃,因为它假设JavaScript引擎已进入无限循环。
正如NullUserException所说,there are better ways of finding primes.
天真的改进只是检查数量小于其平方根的因子。对于任何数字 a ,其中 a = b * c ,您可以假设 b 或 c 小于 a 的平方根。由于您只需知道一个因素就知道数字不是素数,您只需要查找小于其平方根的因子。正如lanzz评论的那样,你也可以跳过偶数。
function isPrime(n)
{
if (n % 2) return false;
var s = Math.sqrt(n);
// iterate by 2 to skip even numbers
for (var i = 3; i <= s; i += 2)
if (n % i) return false;
return true;
}
var total = 3; // 1 + 2
// iterate by 2 to skip even numbers
for (var i = 3; i < 2000000; i += 2)
if (isPrime(i)) total += i;
不要误会我;这不会改变算法的 O 复杂性,并且您仍然会使用足够大的数字来破坏JavaScript引擎。但它会提高它崩溃的次数。我不确定它是否能达到200万。
答案 1 :(得分:0)
尝试使用此功能,它使用比您更快的算法,并且不会因2M数而崩溃:
function isPrime( num ) {
var testNum = 3;
var limitNum = num;
if ( num == 2 )
return true;
if ( num % 2 == 0 )
return false;
while ( limitNum > testNum ) {
if ( num % testNum == 0 ) {
return false;
}
limitNum = parseInt( num / testNum );
testNum += 2;
}
return true;
}
我发现它是VB代码here,我只是将其翻译为Javascript。