为什么我的功能在我使用 splice 时不起作用?

Why won't my function work when I use splice?

我正在尝试编写一个函数,该函数应该计算输入参数和 return 之前的所有质数。我这样做是为了练习。

我用几种方法编写了这个函数,但我试图找到新的方法来实现更多的练习和更好的性能。我最后尝试的是下面的代码:

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,但我认为这与问题无关。

你的问题在这个循环中:

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

这个 for 循环将永远循环下去,因为在您测试的任何情况下,j 总是小于或等于 num。很难准确确定此代码何时开始无限循环,因为您在循环时正在修改列表。

实际上,splice 命令将被调用,将 s 中的某些索引设置为 0,这意味着 j+=s[i] 将不再让您退出循环.

你的问题出在这一行:

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));