运行此脚本时,javascript在浏览器中崩溃,出了什么问题?

时间:2012-10-24 21:28:40

标签: javascript primes

我正在尝试使用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)。这有什么问题?我该如何解决?谢谢你的帮助。

2 个答案:

答案 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。