0

次のコードがあり、10までのすべての素数を合計しようとしています。

この質問に対して最も効率的なコードや正しいコードを見つけようとはしていませんが、forループがどのように機能しているかを把握するのに苦労しています。私は具体的にいつを意味しi = 7ます。

ネストされたforループが2つあるので、何らかの理由でi = 7外側のループが複数回ループしています。つまり、内側のループはj < kその時点で終了状態にj = 2達しているように見えますがk = 2、ループを継続することを主張しているように見えます。

コードは次のとおりです。

var array = [2];
var total = 0; 
function isPrime(i, j) {
    if ( i%array[j] === 0 ) {
        console.log("Not P Check: i was " + i + ", j was " + j + " and k was " + k);
        console.log(i + " is not a prime");
        k = j;
    }
    else if ((j + 1) === array.length) {
        console.log(i + " is a prime");
        total += i;
        console.log("total so far is " + total);
        array.push(i);
        console.log(array);
        k = j;
        console.log("is P Check: i was " + i + ", j was " + j + " and k was " + k);
    }
    else {
        j++;
        console.log("Check " + (j + 1) + ": i is " + i + ", j is " + j + " and k is " + k);
        isPrime(i,j);
    }
}

for(var i = 3; i <=10; i++) {
   var k = array.length;
   for(var j = 0; j < k; j++) {
       console.log("Check 1: i is " + i + ", j is " + j + " and k is " + k);
       isPrime(i, j);
   }
}

console.log(total);
console.log(array);
4

2 に答える 2

0

答えは、ソリューションでは内部ループは不要であるということです。あなたの再帰関数はすでに内側のループの仕事をしています。内側のループで起こることは、いくつかの数字がすべて必要以上に繰り返されることです。

Dygestorのソリューションは1つのアプローチです。他のアプローチはより簡単です

for(var i = 3; i <= 10; i++) {
  isPrime(i, 0);
}

メソッドのログ:

Check 1: i is 3, j is 0 and k is 1
3 is a prime
total so far is 3
[2, 3]
is P Check: i was 3, j was 0 and k was 0
Check 1: i is 4, j is 0 and k is 2
Not P Check: i was 4, j was 0 and k was 2
4 is not a prime
Check 1: i is 5, j is 0 and k is 2
Check 2: i is 5, j is 1 and k is 2
5 is a prime
total so far is 8
[2, 3, 5]
is P Check: i was 5, j was 1 and k was 1
Check 1: i is 6, j is 0 and k is 3
Not P Check: i was 6, j was 0 and k was 3
6 is not a prime
Check 1: i is 7, j is 0 and k is 3
Check 2: i is 7, j is 1 and k is 3
Check 3: i is 7, j is 2 and k is 3
7 is a prime
total so far is 15
[2, 3, 5, 7]
is P Check: i was 7, j was 2 and k was 2
Check 1: i is 7, j is 1 and k is 2
Check 3: i is 7, j is 2 and k is 2
Check 4: i is 7, j is 3 and k is 2
Not P Check: i was 7, j was 3 and k was 2
7 is not a prime
Check 1: i is 7, j is 2 and k is 3
Check 4: i is 7, j is 3 and k is 3
Not P Check: i was 7, j was 3 and k was 3
7 is not a prime
Check 1: i is 8, j is 0 and k is 4
Not P Check: i was 8, j was 0 and k was 4
8 is not a prime
Check 1: i is 9, j is 0 and k is 4
Check 2: i is 9, j is 1 and k is 4
Not P Check: i was 9, j was 1 and k was 4
9 is not a prime
Check 1: i is 10, j is 0 and k is 4
Not P Check: i was 10, j was 0 and k was 4
10 is not a prime
15
[2, 3, 5, 7]

内側のループを削除するログ(これには内側のループの内側も欠落していることconsole.logに注意してください):

3 is a prime
total so far is 3
[2, 3]
is P Check: i was 3, j was 0 and k was 0
Not P Check: i was 4, j was 0 and k was 0
4 is not a prime
Check 2: i is 5, j is 1 and k is 0
5 is a prime
total so far is 8
[2, 3, 5]
is P Check: i was 5, j was 1 and k was 1
Not P Check: i was 6, j was 0 and k was 1
6 is not a prime
Check 2: i is 7, j is 1 and k is 0
Check 3: i is 7, j is 2 and k is 0
7 is a prime
total so far is 15
[2, 3, 5, 7]
is P Check: i was 7, j was 2 and k was 2
Not P Check: i was 8, j was 0 and k was 2
8 is not a prime
Check 2: i is 9, j is 1 and k is 0
Not P Check: i was 9, j was 1 and k was 0
9 is not a prime
Not P Check: i was 10, j was 0 and k was 1
10 is not a prime
15
[2, 3, 5, 7] 

また、k新しいソリューションでは変数は不要です。j素数配列の最後に到達するまで、またはターゲット数が除算可能になるまで、どちらか早い方まで増分します。

内部ループソリューションを使用する場合は、再帰関数を削除して、次のようなことを行う必要があります。

var primes = [2];
var sum = 0;

// Start looping
for(var i = 3; i <= 10; ++i) {
  var prime = true; // Prime until proven innocent
  for(var j = 0; j < primes.length; ++j) { // Length stays same until later
    if(i % arr[j] === 0) { // The meat of your isPrime function: divisible?
      prime = false;
      break; // Stop the loop early: number is not prime!
    }
  }
  if(prime) { // We have a prime!
    primes.push(i); // Add it to our list of primes
    sum += i; // Add the prime to the sum
  }
}

// Log the result
console.log("The sum of primes up to 10 (inclusive)", sum);
console.log("These primes were", primes);
于 2013-02-15T09:23:17.453 に答える
0

http://jsfiddle.net/yLby9/でフィドルを作成し、数行編集しました。基本的に、isPrimeを変更してブール値を返し、素数が見つかるとループを中断するように指示しました。あなたのバージョンでは、7になると、7が配列にプッシュされました(array.lengthが増加しました)。7が素数であることがすでにわかったので、内側のループから抜け出し、別のiを続行します。

var array = [2];
var total = 0; 
function isPrime(i, j) {
    if ( i%array[j] === 0 ) {
        console.log("Not P Check: i was " + i + ", j was " + j + " and k was " + k);
        console.log(i + " is not a prime");
        k = j;
        return false;
    }
    else if ((j + 1) === array.length) {
        console.log(i + " is a prime");
        total += i;
        console.log("total so far is " + total);
        array.push(i);
        console.log(array);
        k = j;
        return true;
        console.log("is P Check: i was " + i + ", j was " + j + " and k was " + k);
    }
    else {
        j++;
        console.log("Check " + (j + 1) + ": i is " + i + ", j is " + j + " and k is " + k);
        return isPrime(i,j);
    }
}

for(var i = 3; i <=10; i++) {
   var k = array.length;
   for(var j = 0; j < k; j++) {
       console.log("Check 1: i is " + i + ", j is " + j + " and k is " + k);
       if (isPrime(i, j)) break;
   }
}

console.log(total);
console.log(array);
于 2013-02-15T09:07:23.250 に答える