【问题标题】:Javascript Prime Factorization code freezes with large numbersJavascript 素数分解代码因大量数字而冻结
【发布时间】:2017-07-26 12:31:43
【问题描述】:

我制作了这个运行良好的素数分解程序。唯一的问题是,当输入很大时,它会冻结浏览器。我的目标是让整个计算持续更长时间,而不是冻结浏览器。我已经尝试了几种方法来解决这个问题。首先我尝试使用async + await sleep(ms)(我在for循环中输入了await sleep,因为我认为它们导致了过度计算问题)但由于某种未知原因它根本没有给出答案。我还尝试将函数拆分为三个较小的函数(每个 for 循环一个)并为每个函数使用 setTimeout,但效果不佳。我知道,可能有更简单的素数分解程序,但我想研究这个,因为我自己想出来了。顺便说一句,第一个调用的函数是factor1(num)

function factor1(num) {
    if (primecheck(num)){
        document.getElementById("resultingz").innerHTML = num + " is prime";
    }else{
        var finalito = [];
        factor2(num, finalito);
    document.getElementById("resultingz").innerHTML = finalito.toString();
    }
}

function factor2(num, arrada){
    var factors = [];
    var factornums = [];

        for (coun = 2; coun <= num/2; coun++) {
            if (num % coun == 0) factornums.push(coun);

        }

        for (i=0; i < factornums.length; i++){
            if (primecheck(factornums[i])){
                factors.push(factornums[i]);
            }
        }
        for (i = 0; i < factors.length; i++){
            rightnow = factors[i];
            while (num % rightnow == 0) {
                arrada.push(factors[i]);
                rightnow = rightnow * factors[i];
            }
        }

    }   

function primecheck(num){
    var primestate = true;
    for (coun = 2; coun <= Math.sqrt(num); coun++) {
            if (num % coun == 0) primestate = false;
        }
        return primestate;
}

【问题讨论】:

  • 定义“大数”。它在哪里结冰?调试应该很容易就能告诉你。
  • 当我输入超过 6 位数的数字时,它开始冻结浏览器。
  • 它“冻结”的行是: for (coun = 2; coun
  • @NiXt “冻结”是指浏览器在(或多或少)短时间内无响应,还是永远完全冻结?
  • 请向我们展示您尝试过的await sleep 解决方案,它应该可以正常工作。

标签: javascript primes


【解决方案1】:

一些改进:

function factor2(num, arrada){
    for (coun = 2; coun <= num/2; coun++) {//one loop instead of three
        if (num % coun == 0 && primecheck(coun)){
          var rightnow=coun;
          while (num % rightnow == 0) {
            arrada.push(coun);
            rightnow = rightnow * coun;
          }
        }
    }
}   

function primecheck(num){
   var primestate = true,num=Math.sqrt(num);//performance improvement
   for (var coun = 2; coun <=num; coun++) {
        if (num % coun == 0){
         primestate = false;
         break;//stop loop if false found
       }
    }
    return primestate;
}

如果你替换一个简单的 for 循环,你可以轻松地异步循环:

for(var counter=start;counter<max;counter++){
 code;
}
end();

使用伪递归函数:

(function iterate (counter){
  if(counter>=max) return end();//end is a callback

  code;

 setTimeout(iterate,0,counter+1);//next tick, continue with counter+1
})(start);//start the function with a start value

【讨论】:

  • 首先,我从来没有使用过伪递归函数,也不知道它们是如何工作的,所以我想对此进行更多解释。另外,我刚刚尝试了您提出的改进代码,但它对我不起作用。
  • @NiXt,是的,我会添加 ab 解释,但是 没有用对我没有帮助...
  • 嗯,它没有给出正确答案,比如我刚试了50,答案是2,5,5,10
  • @NiXt 你确定你的函数返回的东西不同吗?
  • 是的,我检查了他们两个相同的数字。我的函数返回 2,5,5
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多