【问题标题】:javascript crashes in a browser when running this script, what's wrong?运行此脚本时,javascript 在浏览器中崩溃,出了什么问题?
【发布时间】:2012-10-15 00:21:23
【问题描述】:

我正在尝试使用 javascript: 从http://projecteuler.net 解决一个数学问题:找到所有低于 200 万的素数的总和。当我运行我编写的脚本时,我的浏览器崩溃了(我使用的是 Google Chrome)。这是脚本:

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

【问题讨论】:

  • 可能是服务器超时.. 可能需要提高 .htaccess 中的超时限制..
  • @McMastermind - 这看起来像是一个纯 Javascript 问题。为什么会涉及到服务器?
  • 这是一个沉重的紧循环。它可能只是长时间占用您的浏览器。
  • better ways to find primes,你知道...即使将你的测试条件更改为sqrt(num) 而不是num 也会大大提高你的性能。您正在以最艰难的方式做到这一点。
  • 看看this post 它会告诉你如何在 Chrome 中延长运行时间

标签: javascript primes


【解决方案1】:

isPrime 函数为您检查的每个 n 执行 n 模运算(因为您检查每个小于素数的单个数字作为一个因素)。假设about one in every seven numbers is prime,这意味着您在sn-p 中执行了大约28,000 次isPrime 函数,并且您正在执行the modulo operation about 392 million times。很可能,Chrome 正在崩溃,因为它假定 JavaScript 引擎已进入无限循环。

正如 NullUserException 所说,there are better ways of finding primes.

一个简单的改进是只检查小于其平方根的数字的因子。对于 a = b * c 的任何数字 a,您可以假设 bc 小于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 万。

【讨论】:

  • @antonparker 我改为跳过偶数,并延长了 Chrome 中的运行时间,但正如你所说,这将需要很长时间......我在 20 多分钟后放弃了。我已经将函数 isPrime 修改为不同的方法,并且它立即工作。谢谢
  • 很高兴我能帮上忙。就像我说的,我的例子并没有改变大的 O 复杂性,所以我的编辑只是解决这个问题的一个小创可贴!有效地寻找素数是数学研究的一个活跃领域,有很多有趣的方法可以快速完成。
  • @antonparker 我已经研究了一些寻找素数的方法,但到目前为止只有少数对我有意义,我只是从 javascript 开始。再次感谢。
  • 您的isPrime() 功能完全损坏。 1) for 循环仅迭代 even 因子。 2) if 测试条件错误地使用 s 而不是您的 i 变量。谁赞成这个?
  • 哎呀,修复了这些。我多次编辑了 sn-p 并没有测试编辑。关于赞成评论,我会断言即使有这些错误,这篇文章也是有帮助的。我不得不问你为什么不只是编辑帖子来修复这么小部分代码?
【解决方案2】:

试试这个函数,它使用的算法比你的快得多,而且不会因为 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。

【讨论】:

  • 这很有帮助,谢谢!我已经改变了函数,我很快就得到了结果:)
  • 错了。您误译了链接中的代码。它有一个TestLimit 并设置为TestPrime / TestNum(使用/ 进行整数除法而不是VB 的\)。如果您更改候选 num,您将得到完全虚假的结果(尝试 35 例如:35 % 3 != 0,因此 num = parseInt(35/3) = 1111 % 5 != 0,因此 num = parseInt(11/5) = 22 &lt; 7,嘿,num 是素数!)。
  • @DanielFischer 你说得对。我试图缩短功能,但我错过了那部分。我刚刚修好了(我希望)。干杯!
  • 现在应该是正确的。但通常,while(testNum*testNum &lt;= num) 更快(除法慢,乘法快)。
  • 我不知道,我一定会测试它。
猜你喜欢
  • 2012-06-07
  • 1970-01-01
  • 2016-10-11
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2021-12-31
  • 2021-10-03
相关资源
最近更新 更多