2014-02-07 39 views
0

我寫了一個程序來計算斐波那契數,並且它工作正常。然後我改變了程序,給了我斐波那契數65536模數,我所有的輸出都變成了零。什麼地方出了錯?添加模數函數後,所有輸出爲零

import time 
def fib_matrix_timed(min): 
    timeout = time.time() + 60*min 
    A = [0, 1] 
    i = 1 
    while time.time() < timeout: 
     try: 
      B = A 
      A[0] = B[1] 
      A[1] = ((B[0] + B[1])%65536) 
      print A[0] 
      i+=1 
     except OverflowError: 
      print "fib_iterative overflows at ", i 
    print A[0] 
    print "fib_matrix calculated ", i, "iterations in", min, "minute(s)" 

fib_matrix_timed(1) 
+0

在循環中打印'B'而不是'A [0]'顯示:[0,1]', '[1,2]', '[2,4]', '[4 ,[8,16]', '[16,32]', '[32,64]', '[64,128]', '[128,256]', '[256,512]', '[512,1024]', '[1024,2048]', '[2048,4096]', '[4096,8192]', '[8192, 16384]', '[16384,32768]', '[32768,0]', '[0,0]',當然從那裏打印出0。這與B中的列表是對A中列表的引用,而不是列表的單獨副本。 –

回答

1

您的問題是:

B = A 

列表中蟒是mutable,這意味着當你做到這一點,A是相同的對象爲B,而不是一個新的列表。因此,無論何時更改列表A或列表B,您都可以同時更改兩個列表。

這條線可以替換爲:

B = [A[0], A[1]] 

或者:(由MarcosModenesi建議)

B = A[:] # works for list of any size containing immutable objects 

而不是使乙只是爲了相同的對象作爲基準的,這將完全創建新實例,以及原始值。

例如

的下面示出的問題,當B是相同的列表爲A.

假設A是[0,1]:

B = A 

現在B是A是[0,1]

A[0] = B[1] 

B 1是1,所以現在A [0]是B [0]是1.A和B現在都是[1,1]。

A[1] = (B[0] + B[1]) % 65536 

A和B是現在[1,2]

這樣產生的序列是1,2,4,8,16,32 ....

由於65536是2^16,即序列中的第17個數,當然模將是2^16 * 2^n%2^16 = 0.

問題出現在列表B的錯誤實例化中,導致生成的序列爲不正確。

+0

這看起來似乎合理,但並沒有真正解釋爲什麼它與A [1] =(B [0] + B [1])一起工作而不是'A [1] =((B [0] + B [ 1])%65536)'。 –

+0

真的,喬納森。但是,冰樹的建議確實解決了這個問題。 – hannah

+1

一個簡單的方法,擺脫枚舉新列表中的所有項目(這可能是更多)是'B = A [:]' – 2014-02-07 02:40:13