我正在尝试编写一个函数,该函数应计算直至输入参数的所有素数并返回它。我这样做是为了练习。
我以几种方式编写了此函数,但是我试图寻找新的方法来实现此目的,以进行更多的练习和更好的性能。我尝试的最后一件事是下面的代码:
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,但我认为这与问题无关。
答案 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>