改善腦迴路1 斐波那契數列

2021-07-31 18:23:52 字數 4751 閱讀 2691

筆者是一枚準備找工作的新手,為了準備一些演算法思想,開啟了改善腦迴路計畫。記錄我思考問題的過程,如果能啟發一下其他道友就更好了。標題原創,各位大大別亂用哈~

斐波那契(fibonacci)數列是乙個非常簡單的遞迴數列,除第乙個和第二個數外,任意乙個數都可由前兩個數相加得到。形如:1, 1, 2, 3, 5, 8, 13…

要求就是:乙個函式fibonacci(n),接受引數n為數列的長度,返回物件是長度為n的斐波那契數列

宣告:程式用的是python

第一步,寫關鍵部分的**。返回斐波那契數列中的數,基本規律是這乙個數等於前兩個數相加:result = late1 + late2。其中,三個數的順序是...late1, late2, result...。由此可見,返回斐波那契數列中的乙個數需要前面兩個數已知。所以,不僅要為返回值設定變數result,還要為計算值設定兩個變數late1late2

def

fib(n, late1, late2):

if n < 0:

'''報錯'''

elif n == 0

or n == 1:

return

1elif n >= 2:

result = late1 + late2

return result

問題來了:哪兒來的late1和late2以供計算呢,畢竟整體而言,只有乙個輸入引數,那就是n。**第二步,解決第一步剩餘的相關問題。**late1和late2也是數列中的數,是之前計算的result,那麼,在每次計算result的時候,我們都應該保留兩個值(當前計算出的返回值及其前乙個數)以供計算下乙個result。

def

fib(n, late1, late2):

if n < 0:

'''報錯'''

elif n == 0:

return

0, 1

elif n == 1:

return

1, 1

elif n >= 2:

result = late1 + late2

return late2, result

deffibonacci

(n):

late, cur = 1, 1

# 初始當前值為1,前乙個值為1

rslist = # 數列的儲存列表

for i in range(n):

late, cur = fib(i, late, cur)

print rslist

'''產生乙個長度為10的fibonacci數列'''

for x in fibonacci(10):

print x,

# 輸出為[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

第三步,對**中的特殊情況特殊處理。要求輸入的n必須為大於0的整數。在這裡,先預設輸入的都是整數,只對n<0的情況進行處理。n<0時,不返回值並且丟擲引數異常。

def

fib(n, late1, late2):

if n == 0:

return

0, 1

elif n == 1:

return

1, 1

elif n >= 2:

result = late1 + late2

return late2, result

deffibonacci

(n):

if n <= 0:

'''報錯'''

print

'error'

raise valueerror, 'n must be an integer greater than zero!!'

late, cur = 1, 1

# 初始當前值為1,前乙個值為1

rslist = # 數列的儲存列表

for i in range(n):

late, cur = fib(i, late, cur)

return rslist

一般**都有三個要求,基本要求是功能,高階要求是效率,終極要求是可復用。到此我們已經完成了基本功能要求了,筆者當下心滿意足,先去玩耍了~

最近看到別人寫的乙個更簡單的方式, 如下:

def

fib(n):

n, late, result = 0, 0, 1

rslist =

while n < max:

late, result = result, late + result

n = n + 1

return rslist

deffibonacci

(n):

if n <= 0:

'''報錯'''

print

'error'

raise valueerror, 'n must be an integer greater than zero!!'

else:

return fib(n)

具體改進的關鍵點有三個:

我們的**中需要儲存當前返回值和它之前的值。斐波那契數列第乙個數是1, 它前面並沒有其他數了,但是,因為我們只是用儲存的兩個數進行相加來計算返回值,所以,

可以將第零個數設為0。

當輸入為2時,函式需要返回[1, 1]。計算時, 第二個數通過上面的方法,計算為result = late1 + late2 = 0 + 1。但是第乙個數的計算怎麼辦?

可以採用先儲存結果在計算的方式(跟籬笆樁的情況不太一樣),雖然最後會多算乙個多餘值,不過無傷大雅。

現在fib()函式的引數只要乙個。兩個函式的結構稍作了改變。

如果因為輸入n特別大,可能導致輸出的列表特別大,造成記憶體溢位。為了控制儲存空間,我們應該將輸出的列表用generator生成器來表示。

舉個生成器和普通可迭代物件(list)的列子:

iter_list = range(10)  # 普通可迭代物件

gene_list = xrange(10) # 生成器

print

type(iter_list)

print

type(gene_list)

for i in iter_list:

print i,

for i in gene_list:

print i,

print

print iter_list

print gene_list

---輸出↓↓↓---

'list'>

'xrange'>01

2345

6789

0123

4567

89[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

xrange(10)

可以看出:

生成器和普通迭代器的效果是一樣的

但是他們的直接列印結果不一樣,是因為普通迭代器是先產生了整個陣列並儲存在記憶體中;而生成器只是乙個生成資料的方式,當有需要的時候才會產生下乙個值,因此也更省記憶體空間。

用乙個生成器來實現斐波那契額數列:

class

fab(object):

def__init__

(self, max):

self.max = max

self.n, self.a, self.b = 0, 0, 1

def__iter__

(self):

return self

defnext

(self):

if self.n < self.max:

r = self.b

self.a, self.b = self.b, self.a + self.b

self.n = self.n + 1

return r

raise stopiteration()

或者是利用python的yield命令:

# 簡介版,使用yield

deffab

(max):

n, a, b = 0, 0, 1

while n < max:

yield b

a, b = b, a + b

n = n + 1

結果都是一樣的:

for n in fab(10):

print n,

---輸出↓↓↓---11

2358

1321

3455

在 for 迴圈執行時,每次迴圈都會執行 fab 函式內部的**,執行到 yield b 時,fab 函式就返回乙個迭代值,下次迭代時,**從 yield b 的下一條語句繼續執行,而函式的本地變數看起來和上次中斷執行前是完全一樣的,於是函式繼續執行,直到再次遇到 yield。

斐波那契數列 斐波那契數列python實現

斐波那契數列 fibonacci sequence 又稱 分割數列 因數學家列昂納多 斐波那契 leonardoda fibonacci 以兔子繁殖為例子而引入,故又稱為 兔子數列 指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 在數學上,斐波納契數列以如下被以遞推的方法定義 f 1 ...

迴圈斐波那契數列 斐波那契數列應用

什麼是斐波那契數列 斐波那契數列指的是這樣乙個數列 1,1,2,3,5,8,13,21,34,55,89,144 這個數列從第3項開始,每一項都等於前兩項之和 台階問題 有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?這就是乙個斐波那契數列 登上第一級台階有一...

斐波那契數列

1 題目描述 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項。斐波那契數列的定義如下 輸入 輸入可能包含多個測試樣例,對於每個測試案例,輸入包括乙個整數n 1 n 70 輸出 對應每個測試案例,輸出第n項斐波那契數列的值。2 這是九度上的乙個題,要求時間限制1秒,整數的...