我试图将所有素数加起来为数字。
首先,我删除了所有的平均值,然后将其余的推到了一个奇数阵列。
然后我越过数组并拼接除了其他数字但除了1和它们自己的所有数字,并将它们替换为零。
但是,在我的第一个console.log中注意到最后一个元素是977(通过了数字)。
一行后来我为每个阵列打印所有数字超过970,但977不在那里:/
关于这是怎么发生的任何想法? (我排除了伏都教..)
function sumPrimes(num) {
var arr = [2];
for (var i = 3; i <= num; i++) {
if (i % 2 !== 0) {
arr.push(i);
}
}
console.log(arr);
arr.forEach(function(x) {
if(x > 970){
console.log(x);
}
if (x > 3) {
for (var j = 3; j < x; j += 2) {
if (x % j == 0) {
arr.splice(arr.indexOf(x), 1, 0);
}
}
}
})
// console.log(arr);
var res = arr.reduce(function(acc, val) {
return acc + val;
}, 0)
console.log(res);
}
sumPrimes(977);
答案 0 :(得分:5)
问题在于你是如何操纵数组的,而数组实际上最终不会包含977.
你会发现一个非素数并改变数组,使它现在为0,但你继续对该素数进行检查。
这会导致对该值的任何后续indexOf查找返回-1,因此会得到意外结果。
if (x % j == 0) {
arr.splice(arr.indexOf(x), 1, 0); // This won't work after the first assign to 0
}
您可以通过插入“中断”轻松解决此问题紧接着接头以使回路短路,但是你可以很容易地简化和使用forEach中可用的索引参数显着提高速度,以完全删除数组位置查找。
function sumPrimes(num) {
var arr = [2];
for (var i = 3; i <= num; i++) {
if (i % 2 !== 0) {
arr.push(i);
}
}
console.log(arr);
arr.forEach(function(x, idx) {
if(x > 970){
console.log(x);
}
if (x > 3) {
for (var j = 3; j < x; j += 2) {
if (x % j == 0) {
arr[idx] = 0;
break;
}
}
}
})
// console.log(arr);
var res = arr.reduce(function(acc, val) {
return acc + val;
}, 0)
console.log(res);
}
sumPrimes(977);
编辑:如果有人想要一种简单,更有效的方法来确定数字是否为素数,我建议使用Trial Division方法,而不是上面的方法。
您可以在Rosetta code找到一个简洁,经过良好测试的示例:
function isPrime(n) {
if (n == 2 || n == 3 || n == 5 || n == 7) {
return true;
} else if ((n < 2) || (n % 2 == 0)) {
return false;
} else {
for (var i = 3; i <= Math.sqrt(n); i += 2) {
if (n % i == 0)
return false;
}
return true;
}
}
console.log(isPrime(977));
答案 1 :(得分:1)
戴夫的回答是正确的,但为了这个练习,另一个循环解决方案
function sumPrimes(num) {
var prime = [2];
var isPrime;
for (var i = 3; i <= num; i++) {
if (i % 2 !== 0) {
isPrime = true;
prime.forEach(function (v) {
isPrime = isPrime && i % v != 0;
});
if (isPrime) {
prime.push(i);
}
}
}
console.log(prime);
var res = prime.reduce(function (acc, val) {
return acc + val;
}, 0)
console.log(res);
}
sumPrimes(977);
答案 2 :(得分:0)
正如@Dave L也发现的那样,问题似乎就是这个问题:
if (x > 3) {
for (var j = 3; j < x; j += 2) {
if (x % j == 0) {
arr.splice(arr.indexOf(x), 1, 0);
}
}
}
}
当我评论它时,977被打印出来了,但是当它就位时,我不得不尝试使用979打印977.你可能从未怀疑它的原因是因为JavaScript是异步的,所以这实际上得到了解释之前日志声明!
答案 3 :(得分:0)
在使用array.reduce时,为什么不使用array.map为数组设置初始值(而不是使用for循环)?
function seedArray(start, end) {
return Array.apply(null, new Array(end - start + 1)).map(
function(x, i) {
return i + start;
}
);
}
当然你可以做一些错误检查,以确保p1和p2是非负整数,p2&gt; = p1,以确保新的Array()不会崩溃。