032 程式碼複用與函式遞迴
阿新 • • 發佈:2020-12-13
目錄
一、概述
- 程式碼複用與模組化設計
- 函式遞迴的理解
- 函式遞迴的呼叫過程
- 函式遞迴例項解析
二、程式碼複用與模組化設計
2.1 程式碼複用
把程式碼當成資源進行抽象
- 程式碼資源化:程式程式碼是一種用來表達計算的"資源"
- 程式碼抽象化:使用函式等方法對程式碼賦予更高級別的定義
- 程式碼複用:同一份程式碼在需要時可以被重複使用
函式 和 物件 是程式碼複用的兩種主要形式
函式:將程式碼命名
在程式碼層面建立了初步抽象
物件:屬性和方法
<a>.<b>
和 <a>.<b>()
在函式之上再次組織進行抽象
2.2 模組化設計
分而治之
- 通過函式或物件封裝將程式劃分為模組及模組間的表達
- 具體包括:主程式、子程式和子程式間關係
- 分而治之:一種分而治之、分層抽象、體系化的設計思想
緊耦合 鬆耦合
- 緊耦合:兩個部分之間交流很多,無法獨立存在
- 鬆耦合:兩個部分之間交流較少,可以獨立存在
- 模組內部緊耦合、模組之間鬆耦合
三、函式遞迴的理解
3.1 遞迴的定義
函式定義中呼叫函式自身的方式
3.2 遞迴的兩個關鍵特徵
- 鏈條:計算過程存在遞迴鏈條
- 基例:存在一個或多個不需要再次遞迴的基例
3.3 類似數學歸納法
- 數學歸納法
- 證明當n取第一個值n0n0 時命題成立
- 假設當nknk 時命題成立,證明當n=nk+1n=nk+1 時命題也成立
- 遞迴是數學歸納法思維的程式設計體現
四、函式遞迴的呼叫過程
4.1 遞迴的實現
n!={1n(n−1)!n=0otherwisen!={1n=0n(n−1)!otherwisedef fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
4.2 函式 + 分支語句
- 遞迴本身是一個函式,需要函式定義方式描述
- 函式內部,採用分支語句對輸入引數進行判斷
- 基例和鏈條,分別編寫對應程式碼
4.3 遞迴的呼叫過程
五、函式遞迴例項解析
5.1 字串反轉
將字串s反轉後輸出:s[::-1]
- 函式 + 分支結構
- 遞迴鏈條
- 遞迴基例
def rvs(s):
if s == "":
return s
else:
return rvs(s[1:]) + s[0]
5.2 斐波那契數列
斐波那契數列
F(n)=⎧⎩⎨11F(n−1)+F(n−2)n=1n=1otherwiseF(n)={1n=11n=1F(n−1)+F(n−2)otherwiseF(n)=F(n−1)+F(n−2)F(n)=F(n−1)+F(n−2)
- 函式 + 分支結構
- 遞迴鏈條
- 遞迴基例
def f(n):
if n == 1 or n == 2:
return 1
else:
return f(n - 1) + f(n - 2)
5.3 漢諾塔
- 函式 + 分支結構
- 遞迴鏈條
- 遞迴基例
def hanoi(n, src, dst, mid):
global count
if n == 1:
print("{}:{}->{}".format(1, src, dst))
count += 1
else:
hanoi(n - 1, src, mid, dst)
print("{}:{}->{}".format(n, src, dst))
count += 1
hanoi(n - 1, mid, dst, src)
count = 0
hanoi(3, 'A', 'B', 'C')
print(count)
1:A->B
2:A->C
1:B->C
3:A->B
1:C->A
2:C->B
1:A->B
7
六、單元小結
6.1 程式碼複用與函式遞迴
- 模組化設計:鬆耦合、緊耦合
- 函式遞迴的2個特徵:基例和鏈條
- 函式遞迴的實現:函式 + 分支結構