求 斐波那契數列 是比較經典的題目,今天主要是利用python再複習一遍。
記得第一次接觸fib數列還是小時候算大兔子生小兔子最後求兔子總數的問題,所以呢,第一種解法也是比較“接地氣”的:
# Python 斐波那契數列實現
# 獲取用戶輸入數據
nterms = int(input("你需要幾項?"))
# 第一和第二項
n1 = 0
n2 = 1
count = 2
# 判斷輸入的值是否合法
if nterms <= 0:
print("請輸入一個正整數。")
elif nterms == 1:
print("斐波那契數列:")
print(n1)
else:
print("斐波那契數列:")
print(n1,",",n2,end=" , ")
while count < nterms:
nth = n1 + n2
print(nth,end=" , ")
# 更新值
n1 = n2
n2 = nth
count += 1
運行結果:
你需要幾項? 10
斐波那契數列:
0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 ,
p.s.之前幾個關於循環的例子用的都是for,今天用到的是while,本質上來說這兩個循環其實是互通的,滿足一定條件的話換着寫來寫去就完全是看程序員的心情!順便多提一句,老陌最近才知道關於循環的另一種說法:計數器控制循環-for循環,條件控制循環-while循環,如今想來這種說法是挺貼切的!
不過,兩個加數除了上面中規中矩的寫法外我們還可以利用python的特性寫出一版簡潔的解法:
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fib(1000) # 取值範圍可以任意
# 輸出結果如下:
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
p.s.特地找了一版可以控制最後一個數字範圍的解法,老陌第一次看到的時候也是眼前一亮!
當然,除了循環的方法,遞歸的解題思路也是比較常用的:
def fab(n):
if n == 1:
return 0
if n == 2:
return 1
if n > 2:
return fab(n-1) + fab(n-2)
def printfablist(n):
for i in range(1, n+1):
print(fab(i),end = ' ')
運行實例:
>>>printfablist(int(input('please input a number:')))
please input a number:10
0 1 1 2 3 5 8 13 21 34
遞歸調用的代碼稍顯簡潔,結構也比較清晰,但是由於遞歸佔用較多資源,對於大規模的計算消耗比較大,所以運算比較慢。從運算速度的角度出發,這時候反而選用循環實現更好。
最後,我們肯定也不能放棄“高效”的數學公式!算法是程序的靈魂~
注:此時a1=1,a2=1,an=a(n-1)+a(n-2)(n>=3,n∈N*)
斐波那契數列的通項公式又叫“比內公式”,是用無理數表示有理數的一個範例。
利用通項公式的解法更加簡潔:
#斐波那契數列的通項式爲:f(n) = (5**0.5/5)*(((1+5**0.5)/2)**n - ((1-5**0.5)/2)**n)
N = int(input("請輸入要幾項:"))
if(N < 0):
print("請輸入大於0的數")
else:
for i in range(0,N):
print(int((5**0.5/5)*(((1+5**0.5)/2)**i - ((1-5**0.5)/2)**i)))
p.s.通項公式具體的推導過程可以參考百科,用線代的理論解釋起來也挺好理解的。
參考資料:
菜鳥教程-斐波那契數列 https://www.runoob.com/python3/python3-fibonacci-sequence.html
維基百科-斐波那契數列 https://zh-wiki.info/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97