0

次のプログラムは、素数変数を決定します。1より大きくpより小さいdのすべての値に対して剰余(p%d)を返す値は、isPrimeの値を「1」に設定します。

- (int)someMethod
{
    @autoreleasepool {

        int isPrime;
        for (int p = 2; p <= 50; ++p) {
            isPrime = 1;

            for (int d = 2; d < p; ++d) {

                if ( p % d == 0)
                    isPrime = 0;

                if ( isPrime != 0)
                    NSLog (@"%i ", p);
            }
        }
    }

    return 0;
}

私の質問は、最初の「for」ステートメントが「1」だけインクリメントした直後に進行するのに対し、2番目の「for」ステートメントでは、dの値がp以上になるまでループが進行してから最後に進むのはなぜですか。 「if」ステートメントとNSLog。

この質問が明確でない場合、たとえば、pの値が14の場合、プログラムは次のように進行します。

  1. pは1ずつ増加して15になります
  2. 変数isPrimeは1に設定されます
  3. dの値は2に設定されます
  4. p%dが計算されます。
  5. 結果は0に等しくないため、forステートメントはスキップされます
  6. 次に、dの値は、私が理解できない何らかの理由で3に増分し、dが15に等しくなるまでループが続きます。代わりに、単にifステートメントとNSLogに移動し、「15」と表示されます。 "。2番目の「for」ループが「if」ステートメント内でループを続けてdをインクリメントするのに対し、最初のループはpを1回インクリメントしてから次に進むのはなぜですか?
4

3 に答える 3

2

彼はforループを理解しています。他の回答は質問を理解できていないようです。このループは、素数を正しく決定しません。たとえば、15 も 49 も素数として出力しますが、素数ではない場合もあります。内側のループで印刷を行うため、素数も複数回印刷されます。15を出力する必要があり、ロジックは適切です。それがあなたのためではない理由はわかりませんが、それは私のためです。正しい実装は次のとおりです。

- (int)someMethod {
    int isPrime;
    for (int p = 2; p <= 50; ++p) {
        isPrime = 1;
        for (int d = 2; d < p; ++d) {
            if ( p % d == 0)
                isPrime = 0;
        }
        if (isPrime)
            NSLog (@"%i ", p);
    }
    return 0;
}

うまくいかない理由を説明します。

ある数値が素数かどうかを判断するために、このプログラムは に均等に割り切れる数値があるかどうかを調べる必要がありますp。素数が見つかるとすぐに、その数は素数ではなくなり、 に設定isPrimeする必要があり0ます。未満のすべての数値をチェックしp、したがって決定されたら、数値を出力する必要があるかどうかをisPrime確認する必要があります。isPrimeただし、代わりにisPrime、数値が に均等に分割されるかどうかをチェックするたびにチェックしますpisPrimeのすべての値の開始時に が 1 に設定されているため、p2 で割り切れない数値が出力されます。2 が均等に分割されるかどうかを確認します。そうでない場合は、すぐに確認しますisPrimeこれは 1 であり、素数であるかのようにすぐに出力します。しかし、数 AFTER 2 がその数に均等に分割されるとどうなるでしょうか? これが、15 と 49 が合成されたときに素数として出力される理由です。

于 2012-09-03T03:01:42.330 に答える
0

あなたにとって不明確なことはわかりません。

問題:pが素数かどうかを調べます。

pとそれ自体を除いて、d <= pそのような因数を持たない場合、 は素数です。内部の for は、 よりも小さいすべての数値をループして、それらのいずれも の因数にならないようにする必要があります。p%d == 01ppp

この実装は自明なものであり、非効率的であることに注意してください。素数の暗黙の定義が何であるかを実行します。

あなたを混乱させるかもしれない唯一のことは、要因が見つかったときに内側のループが中断されないという事実です。

if ( p % d == 0)
{
  isPrime = 0;
  NSLog("number is not prime!);
  break;
}
于 2012-09-03T00:48:20.067 に答える
0

「私の質問は、最初の "for" ステートメントが "1" だけインクリメントした直後に進むのに対し、2 番目の "for" ステートメントでは、d の値が p より小さくなくなるまでループが続くのはなぜですか?最終的な「if」ステートメントと NSLog."

for ループの仕組みについて少し混乱しているようです。

// Outer loop will run 1 time
for (int i = 0; i < 1; i++) {
    NSLog(@"Outer loop = %d", i);

    // Innter loop will run 10 times
    for (int j = 0; j < 10; j++) {
        NSLog(@"Inner loop = %d", j);
    }
}

上記のループは、次の出力を出力します。

Outer loop = 0
Inner loop = 0
Inner loop = 1
Inner loop = 2
Inner loop = 3
Inner loop = 4
Inner loop = 5
Inner loop = 6
Inner loop = 7
Inner loop = 8
Inner loop = 9

編集:

- (int)isPrime
{
    @autoreleasepool {

        // Outer loop will run once to check if 15 is prime
        for (int p = 15; p <= 15; ++p) {

            // You set isPrime to 1
            int isPrime = 1;

            // Inner loop will start at 2 and run until 14, there is no
            // need to check if 15 % 1 or 15 % 15 because a prime number is
            // divisible by itself or 1
            for (int d = 2; d < p; ++d) {

                NSLog(@"%d mod %d", p, d);

                // The first run through of the inner loop, you check if
                // 15 % 2, this is not true, so you skip to the next loop.
                if (p % d == 0) {
                    isPrime = 0;
                    //break;  // This is optional because at this point, you know p is not prime
                }

                // Remember you set isPrime to 1, so the loop checks if isPrime != 0
                // This statement is true, so you print p which at this point is 15.
                if (isPrime != 0) {
                    NSLog (@"%i ", p);
                }

                // On the next run through of the inner loop, 15 % 3 is equal to
                // 0, so you set isPrime to 0, and for the rest of the inner loop
                // isPrime is equal to 0, it can not change, this is why p is never
                // printed out again
            }
        }
    }

    return 0;
}

内側のループにログ ステートメントを追加しました。先に進んでコードを実行して、何が起こっているかを確認してください。私はこれを言います、あなたのコードは問題ないようです。isPrime が 0 の場合に p が素数であるかどうかはわかるので、break ステートメントを追加することをお勧めします。コードをチェックして、配置する場所を確認します。

于 2012-09-03T00:53:21.000 に答える