使用接头时为什么我的功能不能正常工作?

时间:2018-08-29 17:09:48

标签: javascript sieve-of-eratosthenes

我正在尝试编写一个函数,该函数应计算直至输入参数的所有素数并返回它。我这样做是为了练习。

我以几种方式编写了此函数,但是我试图寻找新的方法来实现此目的,以进行更多的练习和更好的性能。我尝试的最后一件事是下面的代码:

function primes(num){
  let s = []; // sieve
  for(let i = 2; i <= num; i++){
    s.push(i);
  }
  for(let i = 0; i < s.length; i++) {

    for(let j = s[i]*s[i]; j <= num;) {
      //console.log(j);
      if(s.indexOf(j)!= -1){

        s.splice(s.indexOf(j), 1, 0);

      }
      j+=s[i];
    }
  }
  s = s.filter(a => a != 0);
  return s;
}
console.log(primes(10));

问题是,当我在浏览器中运行它时,它会不断计算,并且不会停止,而且我也不知道为什么。

注意:当我注释掉splice并取消注释console.log(j);时,一切都按预期工作,并且日志是应有的,但是使用splice时,浏览器会继续计算,不会停止。

我正在使用最新版本的Chrome,但我认为这与问题无关。

2 个答案:

答案 0 :(得分:3)

您的问题出在这一行:

s.splice(s.indexOf(j), 1, 0);

Splice函数的第三个参数包含要添加的元素,以代替已删除的元素。这意味着您无需删除元素,而是将它们的值交换为0,从而冻结了j循环。 要解决此问题,只需省略第三个参数。

function primes(num){
  let s = []; // sieve
  for(let i = 2; i <= num; i++){
    s.push(i);
  }
  for(let i = 0; i < s.length; i++) {

    for(let j = s[i]*s[i]; j <= num;) {
      //console.log(j);
      if(s.indexOf(j)!= -1){

        s.splice(s.indexOf(j), 1);

      }
      j+=s[i];
    }
  }
  return s;
}
console.log(primes(10));

答案 1 :(得分:0)

您的问题出在此循环中:

for(let j = s[i]*s[i]; j <= num;)

此for循环将永远循环,因为无论您要测试哪种情况,j始终小于或等于num。确定确切的代码何时开始无限循环非常困难,因为您在循环时正在修改列表。

实际上,将调用splice命令,将s中的索引的某些部分设置为0,这意味着j+=s[i]将不再使您陷入困境。 / p>