簡體   English   中英

Python 雙 while 循環不工作,不知道為什么

[英]Python double while loop not working, can't figure why

我知道也許使用“for”可以使代碼更清晰,但我想了解為什么這段代碼不起作用。 此外,該代碼是對 2008 MIT OCW class 練習的改編,其中唯一允許使用的函數是算術函數,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,它進入循環。 然后,primesupport值改為1,因為3/2=1 primesupport大於0,所以進入第二個while循環。 if 條件為真 (3%1=0) 所以代碼進入 if,將 primesupport 更改為 -1 並將 primesofar 增加兩倍。(現在 primesupport=-1 和 primesofar=5)這里有一個問題,因為它離開不打印 3,但讓我們繼續。 當它返回到第二個 while 時,它將收到一個 False,因為 -1 不大於 0。這將使代碼測試第一個 while,並且由於 primecounter 沒有更改,它將再次進入循環。 Primesupport 現在將收到 2(因為 5/2=2)它將進入第二個循環並通過所有循環直到 else 條件。 primesupport 將減少一個(primesupport now =1),while 循環將繼續進入 elif now。 這將打印 5 increase primesofar to 7 decrease primesupport 離開 while 循環並增加 primecounter,回到第一個循環並重新開始。 我承認除了 3 沒有按預期打印外,我看不出我在哪里犯了錯誤。 希望你能指點我。

感謝大家的幫助,尤其是 FallenAngel、John Machin、DiamRem 和 Karl Knechtel 指出了錯誤並展示了調試方法。

我認為這是問題所在:

你被卡住了,因為 primesofar=3 並且在 python 3/2 = 1,所以在 if primesofar%primesupport == 0: 這是 True 因為 1%1 = 0 在 python 和如果 primesofar 是 1+2 的代碼中,然后 primesofar 又是 3 並且你在永恆中從一個時間跳到另一個時間。

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

當代碼到達這一點時,內部循環將被打破,而primecounter改變。 該代碼將使用相同的primecounter值重復相同的步驟,並且必然會到達相同的點; 沒有辦法打破外環。

(盡管跳出循環的正確方法是使用break 。)

我放置了一些print語句,這是您的程序給出的 output:

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塊將primesupport減少到 1,然后在下一個循環中, if primesofar%primesupport == 0:返回 true 並且該塊被執行,您將primesofar增加 2 並開始新的素數檢查...

在測試primesofar % primesupport == 0之前,您需要測試primesupport == 1因為any_integer % 1始終為 0,而當primesupport == 1時您想要執行的代碼並沒有發生。

當你修復它時,你會看到print primesofar+', won't work...你應該能夠自己修復它。

您可以部署的最基本有效的調試技術是 (1) 使用一小組數據,以便您可以理解正在發生的事情,並且您只需一支鉛筆和一張紙就可以檢查結果 (2)打印出正在發生的事情。

(1) while primecounter < 5:

(2) 在第 2 while 之后,

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

您的代碼的問題是每次 primecounter 達到 1 時,您都在檢查 primesofar%primesupport == 0,它總是會這樣做。 所以你的程序永遠不會進入 elif 和 else 部分。 因此素數計數器永遠不會增加。 所以這將是一個無限循環。

您可以通過在 if primesofar%primesupport == 0 之后放置打印語句來檢查這一點:

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 與 + 連接起來。 你可以只打印素數。 打印語句會自動添加換行符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM