第023、024講:遞迴:這幫小兔崽子、漢諾塔
目錄
0. 使用遞迴編寫一個十進位制轉換為二進位制的函式(要求採用“取2取餘”的方式,結果與呼叫bin()一樣返回字串形式)。
1. 寫一個函式get_digits(n),將引數n分解出每個位的數字並按順序存放到列表中。
2. 還記得求迴文字串那道題嗎?現在讓你使用遞迴的方式來求解,親還能驕傲的說我可以嗎?
4. 請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!
動動手
0. 使用遞迴編寫一個十進位制轉換為二進位制的函式(要求採用“取2取餘”的方式,結果與呼叫bin()一樣返回字串形式)。
def Dec2Bin(dec): result = '' if dec: result = Dec2Bin(dec//2) return result + str(dec%2) else: return result print(Dec2Bin(62))
1. 寫一個函式get_digits(n),將引數n分解出每個位的數字並按順序存放到列表中。
舉例:get_digits(12345) ==> [1, 2, 3, 4, 5]
解題思路:利用除以10取餘數的方式,每次呼叫get_digits(n//10),並將餘數存放到列表中即可。要注意的是結束條件設定正確。
result = [] def get_digits(n): if n > 0: result.insert(0, n%10) get_digits(n//10) get_digits(12345) print(result)
2. 還記得求迴文字串那道題嗎?現在讓你使用遞迴的方式來求解,親還能驕傲的說我可以嗎?
解題思路:有好多種方法,不過綜合效率來說,小甲魚的實現方式比較樸素,利用遞迴每次索引前後兩個字元進行對比,當start > end的時候,也正是首尾下標“碰面”的時候,即作為結束遞迴的條件。
def is_palindrome(n, start, end): if start > end: return 1 else: return is_palindrome(n, start+1, end-1) if n[start] == n[end] else 0 string = input('請輸入一串字串:') length = len(string)-1 if is_palindrome(string, 0, length): print('"%s"是迴文字串!' % string) else: print('"%s"不是迴文字串!' % string)
3. 使用遞迴程式設計求解以下問題:
有5個人坐在一起,問第五個人多少歲?他說比第4個人大2歲。問第4個人歲數,他說比第3個人大2歲。問第三個人,又說比第2人大兩歲。問第2個人,說比第一個人大兩歲。最後問第一個人,他說是10歲。請問第五個人多大?
解題思路:利用遞迴的方法,遞迴分為回推和遞推兩個階段。要想知道第五個人歲數,需知道第四人的歲數,依次類推,推到第一人(10歲),再往回推。
def age(n):
if n == 1:
return 10
else:
return age(n-1) + 2
print('哈哈,我知道了,第五個人的年齡是 %d 歲,啵啵脆!' % age(5))
4. 請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!
(1)斐波那契數列的遞迴實現:
1,1,2,3,5,8,13,21.....
我們可以用數學函式來定義:
分別用迭代和遞迴實現:
迭代
def fab(n):
n1 = 1
n2 = 1
n3 = 1
if n < 1:
print("輸入錯誤!")
return -1
while (n-2) > 0:
n3 = n2 + n1
n1 = n2
n2 =n3
n -= 1
return n3
遞迴:
def fab(n):
if n < 1:
print('輸入有誤!')
return -1
elif n == 1 or n == 2:
return 1
else:
return ferber(n-1)+ferber(n-2)
遞迴演算法稱為分治思想。
(2)遞迴實現漢諾塔
對於遊戲的玩法,我們可以簡單分解為三個步驟:
-
將前63個盤子從a移到b上
-
將最底下的第64個盤子從a移到c
-
將b上的63個盤子移到c
問題1:將a上的63個盤子藉助c移到b
問題2:將b上的63個盤子藉助a移到c
然後:
問題1拆解為:
-
將前62個盤子從a移到c上
-
將最底下的第63個盤子從a移到b
-
將c上的62個盤子移到b
問題2拆解為:
-
將前62個盤子從b移到a上
-
將最底下的第63個盤子從b移到c
-
將a上的62個盤子移到b