此代码放置了以下所有素数为200万的素数并计算它们的总和,我不认为素数是错误的,但我收到的总和为143010484903,但正确答案是142913828922
有人可以帮我怎么回事吗?我是JS的新手。
- service:
name: apache
state: started
enabled: yes
答案 0 :(得分:1)
我认为您确实有一些大于2000000
的质数,因为您是在计算平方根后对值进行底数计算。尝试改用.ceil()。您甚至可以使用较小的值进行测试,尝试采用10
和console.log(primes);
,您会发现还有额外的价值11示例[2, 3, 5, 7, 11]
;
let sqrtNum = Math.ceil(Math.sqrt(num));
答案 1 :(得分:1)
我不确定代码中的错误是什么,但是在内部循环的某个地方,您会陷入困境。您的primes.length
也比我的代码长。
let primes = [2];
mainLoop: for (let num = 3; num < 2000000; num += 2) {
let sqrtNum = Math.floor(Math.sqrt(num));
for (let i = 0; primes[i] <= sqrtNum; i++) {
if (num % primes[i] == 0) {
continue mainLoop;
}
}
primes.push(num);
}
let sum = 0;
for (let i = 0; primes[i] < 2000000; i++) {
sum += primes[i];
}
console.log(sum);
和带有筛子的快速版本
var sieve = Array(2000000).fill(false);
var primes = [2];
for(let i=0; i<sieve.length; i+=2) sieve[i] = true;
for(var i=3; i < sieve.length; i+=2){
if(sieve[i]) continue;
primes.push(i);
for(let j=i*i; j<sieve.length; j+=i+i){
sieve[j] = true;
}
}
console.log(primes.reduce((a,b) => a+b));
答案 2 :(得分:1)
您的算法正在将合成添加到素数列表中
let num = 3;
let primes = [2];
while (num < 123) {
let sqrtNum = Math.floor(Math.sqrt(num));
for (i = 0; sqrtNum >= primes[i]; i++) {
if (num % primes[i] == 0) {
num += 2;
i = 0;
} else {
continue;
}
}
primes.push(num);
num += 2;
}
console.log(...primes)
上述列表中的第121号通知(11 x 11)。
问题出在while循环的逻辑以及管理变量num
的方式上。考虑一下在测试复合值时会发生什么。115您将进入循环n = 115
的部分:
let sqrtNum = Math.floor(Math.sqrt(num)); // sqrtNum == 10
for (i = 0; sqrtNum >= primes[i]; i++) { // testing against [2, 3, 5, 7, 9]
if (num % primes[i] == 0) { // on the 3rd loop you find 115
num += 2; // is divisible by 5 and increase
i = 0; // nums to 117,and find it's composite
// eventually nums is 121 but you haven't changed
} else { // sqrtNum to refect you now need to search
continue; // up to 11 so you think 121 is prime
}
}
primes.push(num);
num += 2;
}
这种情况很少发生,这就是为什么您的总和接近的原因。更改为math.ceil
似乎可以解决此问题,因为ceil(Math.sqrt(115))
为11,但是我不确定您如何证明这总是正确的。
一个更好的主意是将筛子张贴在另一个答案中。但这是一个贴近您代码但可以管理num
的修复程序,因此您无需重新计算num
就不会增加sqrtNum
:
let num = 3;
let primes =[2];
while(num <= 130) {
let composite = false
let sqrtNum = Math.floor(Math.sqrt(num)); // sqrtNum will be calculated for each change of num
for(i = 0; sqrtNum >= primes[i]; i++) {
if(num % primes[i] == 0) {
composite = true
break
}
}
if (!composite){
primes.push(num);
}
num += 2
}
// no 121!
console.log(...primes);