1

「for」を使用するとコードが明確になる可能性があることは理解していますが、このコードが機能しない理由を理解したいと思います。また、このコードは 2008 MIT OCW クラスの演習用に改造したものであり、使用が許可されている関数は算術関数、if、elif、else、print、および while のみです。指摘しておくと、コードは最初の 1000 個の素数を出力するはずでした。

print '2, '      #Print the prime 2 to set only odd primes.
primesofar=3     #Set 3 as the first prime
primecounter=1   #Mark 3 as the first prime to test until 1000, otherwise the while below should test to 1001
primesupport=1   #Create primesupport with a integer value
while primecounter<1000:
    primesupport=primesofar/2  #Create a support counter for test the prime. This counter only had to have the half value of the supposed prime, because we only need to try to divide by the primes that are lower than the half of the suppposed prime. In fact it would be better to test for values that are lower than the square root of the supposed prime, but we can't use square root operation yet.
    while primesupport>0:
      if primesofar%primesupport == 0:
        primesupport=-1       #If the remainer of the division is 0, the number isn't prime because it will have more than two divisors so we set primesupport as -1 to exit the while and increase the current primesofar to the next odd number.
        primesofar=primesofar+2
      elif primesupport==1:   #If primesupport is 1, we tested all the numbers below the half of the supposed prime which means the number is prime. So we print it, set the while exit and increase the number of primes counted and go to the next odd number.
        print primesofar+', '
        primesofar=primesofar+2
        primesupport=-1
        primecounter=primecounter+1
      else: 
        primesupport=primesupport-1

迅速な対応に感謝しており、コードに目に見えないブレークがあった可能性があると思います。このため、どこで間違いを犯しているかを指摘しやすくするために、コードが本来すべきことを書き留めようと思います。始めましょう: primesofar は 3 を受け取ります。primecounter は 1 を受け取り、primesupport は 1 を受け取ります。最初の while テストは、primecounter で、primesupport が 1000 未満であるため、ループに入ります。次に、3/2=1 であるため、primesupport の値は 1 に変更されます。primesupport は 0 より大きいため、2 番目の while ループに入ります。if 条件が true (3%1=0) であるため、コードは if に入り、primesupport を -1 に変更し、primesofar を 2 増やします (現在は primesupport=-1 および primesofar=5)。 3を印刷せずに、続けましょう。2 番目の while に戻ると、-1 は 0 より大きくないため、False を受け取ります。これにより、コードは最初の while をテストし、primecounter が変更されていないため、再びループに入ります。Primesupport は 2 を受け取ります (5/2=2 のため)。これは 2 番目のループに入り、else 条件までそのすべてを通過します。Primesupport は 1 つ減少し (primesupport now =1)、while ループは引き続き elif に入ります。これにより、5 increase primesofar to 7 reduce primesupport が出力され、while ループが終了し、primecounter が増加し、最初のループに戻って再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。これにより、コードが最初にテストされ、primecounter が変更されていないため、再びループに入ります。Primesupport は 2 を受け取ります (5/2=2 のため)。これは 2 番目のループに入り、else 条件までそのすべてを通過します。Primesupport は 1 つ減少し (primesupport now =1)、while ループは引き続き elif に入ります。これにより、5 increase primesofar to 7 reduce primesupport が出力され、while ループが終了し、primecounter が増加し、最初のループに戻って再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。これにより、コードが最初にテストされ、primecounter が変更されていないため、再びループに入ります。Primesupport は 2 を受け取ります (5/2=2 のため)。これは 2 番目のループに入り、else 条件までそのすべてを通過します。Primesupport は 1 つ減少し (primesupport now =1)、while ループは引き続き elif に入ります。これにより、5 increase primesofar to 7 reduce primesupport が出力され、while ループが終了し、primecounter が増加し、最初のループに戻って再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。Primesupport は 2 を受け取ります (5/2=2 のため)。これは 2 番目のループに入り、else 条件までそのすべてを通過します。Primesupport は 1 つ減少し (primesupport now =1)、while ループは引き続き elif に入ります。これにより、5 increase primesofar to 7 reduce primesupport が出力され、while ループが終了し、primecounter が増加し、最初のループに戻って再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。Primesupport は 2 を受け取ります (5/2=2 のため)。これは 2 番目のループに入り、else 条件までそのすべてを通過します。Primesupport は 1 つ減少し (primesupport now =1)、while ループは引き続き elif に入ります。これにより、5 increase primesofar to 7 reduce primesupport が出力され、while ループが終了し、primecounter が増加し、最初のループに戻って再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。最初のループに戻り、再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。最初のループに戻り、再び開始します。私は、期待どおりに印刷されていない 3 以外に、どこで間違いを犯しているのかわかりません。ご指摘いただければ幸いです。

エラーを指摘し、デバッグ方法を示してくれた FallenAngel、John Machin、DiamRem、Karl Knechtel に感謝します。

4

5 に答える 5

1
if primesofar%primesupport == 0:
    primesupport=-1

コードがこのポイントに到達すると、内部ループは変更されずに中断されprimecounterます。コードは同じ値で同じ手順を繰り返し、primecounter必然的に同じポイントに到達します。外側のループを壊す方法はありません。

(ループから抜け出す正しい方法は使用することですがbreak。)

于 2012-04-07T08:44:43.800 に答える
1

これが問題だと思います:

primesofar=3 および python 3/2 = 1 でスタックしたため、if primesofar%primesupport == 0: これは True です。なぜなら、python では 1%1 = 0 であり、primesofar が 1+2 である場合のコードでは、その場合、primesofar は再び 3 になり、永遠にある時間から別の時間にジャンプします。

于 2012-04-07T08:30:54.590 に答える
1

いくつかのprintステートメントを配置すると、これがプログラムの出力です。

primesupport 1
primesofar 5
primesupport 2
primesupport 1
primesofar 7
primesupport 3
primesupport 2
primesupport 1
primesofar 9
primesupport 4
primesupport 3
primesofar 11
primesupport 5
primesupport 4
primesupport 3
primesupport 2
primesupport 1
primesofar 13
primesupport 6
primesupport 5
primesupport 4
primesupport 3
primesupport 2
primesupport 1
primesofar 15
primesupport 7
primesupport 6
primesupport 5
primesofar 17
primesupport 8
primesupport 7
...

あなたのコードは決してelif primesupport==1:ブロックに入らないので、primecounter増加することはありません...

テストに使用されるのは次のとおりです。

while primecounter<2:
primesupport=primesofar/2
print 'primesupport %s' % primesupport
while primesupport>0:
    if primesofar%primesupport == 0:
        primesupport=-1 
        primesofar=primesofar+2
        print 'primesofar %s' % primesofar
    elif primesupport==1:
        print primesofar+', '
        primesofar=primesofar+2
        primesupport=-1
        primecounter=primecounter+1
        print 'primesofar %s' % primesofar
        print 'primesupport %s' % primesupport
        print 'primecounter %s' % primecounter
    else:
        primesupport=primesupport-1
        print 'primesupport %s' % primesupport

理由は、最終elseブロックが 1 まで減少primesupportし、次のループでif primesofar%primesupport == 0:true を返し、そのブロックが実行され、primesofar2 増加して新しい素数チェックを開始することです...

于 2012-04-07T09:06:16.757 に答える
1

は常に 0 であり、実行したいコードが発生していないため、テストするprimesupport == 1前にテストする必要があります。primesofar % primesupport == 0any_integer % 1primesupport == 1

それを修正すると、うまくいかないことがわかりますprint primesofar+',...自分で修正できるはずです。

展開できる最も基本的な効果的なデバッグ手法は、(1) 何が起こっているかを理解できるように小さなデータ セットを使用し、鉛筆と紙 1 枚だけで結果を確認できる (2) です。何が起こっているかを印刷します。

(1)while primecounter < 5:

(2) しばらくすると、

print "sofar, support, count", primesofar, primesupport, primecounter

于 2012-04-07T09:07:56.527 に答える
0

コードの問題は、primecounter が 1 になるたびに、primesofar%primesupport == 0 かどうかをチェックしていて、常にそうなるということです。したがって、あなたのプログラムは elif と else の部分に入ることはありません。したがって、素数カウンターはインクリメントされません。なので無限ループになります。

これは、if primesofar%primesupport == 0 の後に print ステートメントを追加することで確認できます。

if primesofar%primesupport == 0:
    print primesofar

primesofar%primesupport == 0 を確認する前に、 primesupport==1 を確認することで修正できます。

print '2, '      #Print the prime 2 to set only odd primes.
primesofar=3     #Set 3 as the first prime
primecounter=1   #Mark 3 as the first prime to test until 1000, otherwise the while below should test to 1001
primesupport=1   #Create primesupport with a integer value
while primecounter<1000:
    primesupport=primesofar/2  #Create a support counter for test the prime. This counter only had to have the half value of the supposed prime, because we only need to try to divide by the primes that are lower than the half of the suppposed prime. In fact it would be better to test for values that are lower than the square root of the supposed prime, but we can't use square root operation yet.
    while primesupport>0:
        if primesupport==1:   #If primesupport is 1, we tested all the numbers below the half of the supposed prime which means the number is prime. So we print it, set the while exit and increase the number of primes counted and go to the next odd number.
            print primesofar
            primesofar=primesofar+2
            primesupport=-1
            primecounter=primecounter+1
        elif primesofar%primesupport == 0:
            primesupport=-1       #If the remainer of the division is 0, the number isn't prime because it will have more than two divisors so we set primesupport as -1 to exit the while and increase the current primesofar to the next odd number.
            primesofar=primesofar+2
        else: 
            primesupport=primesupport-1

このコードは 1000 個の素数を表示します。

ところで、str と int を + で接続することはできません。素数を印刷するだけです。Print ステートメントは自動的に改行を追加します。

于 2012-04-07T09:20:57.073 に答える