[2021 spring] CS61A Lab 3: Recursion, Tree Recursion
阿新 • • 發佈:2021-06-22
lab03: https://inst.eecs.berkeley.edu/~cs61a/sp21/lab/lab03/#topics
Topics
Recursion
遞迴函式是在其主體中直接或間接呼叫自身的函式。 遞迴函式具有三個重要組成部分:
- 基本案例,您嘗試解決的問題的最簡單形式。
- 遞迴情況,其中函式使用更簡單的引數呼叫自身作為計算的一部分。
- 使用遞迴呼叫來解決完整的問題。
通用技巧(機翻):
- 要編寫遞迴函式,你必須在編寫完成之前假設該函式是全功能的; 這被稱為信仰的遞迴飛躍。
- 考慮如何使用更簡單版本的問題的解決方案來解決當前問題。 在遞迴函式中完成的工作量可能很少:記住要大膽地相信遞迴可以解決稍微小的問題,而不必擔心如何解決。
- 想想在最簡單的情況下答案是什麼。 這些將是你的基本情況 - 你遞迴呼叫的停止點。 確保考慮你缺少基本情況的可能性(這是遞迴解決方案失敗的常見方式)。
- 首先編寫一個迭代版本可能會有所幫助。
Tree Recursion
樹遞迴函式是一種遞迴函式,它對自身進行多次呼叫,從而產生一系列類似樹的呼叫。
(以斐波那契數列為例)
通常,當您想在一個步驟中探索多種可能性或選擇時,樹遞迴是有效的。 在這些型別的問題中,您對每個選擇或一組選擇進行遞迴呼叫。 這裡有些例子:
- 給定一份付費任務列表和有限的時間,您應該選擇哪些任務來最大化您的報酬? 這實際上是揹包問題的一種變體,它側重於尋找不同物品的最佳組合。
- 假設您迷失在迷宮中並看到了幾條不同的路徑。 你如何找到出路? 這是路徑查詢的一個示例,並且是樹遞迴的,因為在每一步,您都可以有多個方向可供選擇,從而可以走出迷宮。
- 您的烘乾機每個週期收費 2 美元,可以接受所有型別的硬幣。 您可以建立多少種不同的硬幣組合來執行烘乾機? 這類似於教科書中的分割槽問題。
Coding practice
Q3: Summation
def summation(n, term): """Return the sum of numbers 1 through n (including n) wíth term applied to each number. Implement using recursion! >>> summation(5, lambda x: x * x * x) # 1^3 + 2^3 + 3^3 + 4^3 + 5^3 225 >>> summation(9, lambda x: x + 1) # 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 54 >>> summation(5, lambda x: 2**x) # 2^1 + 2^2 + 2^3 + 2^4 + 2^5 62 >>> # Do not use while/for loops! >>> from construct_check import check >>> # ban iteration >>> check(HW_SOURCE_FILE, 'summation', ... ['While', 'For']) True """ assert n >= 1 "*** YOUR CODE HERE ***" if n == 1: return term(1) else: return summation(n - 1, term) + term(n)
Q4: Pascal's Triangle
def pascal(row, column):
"""Returns the value of the item in Pascal's Triangle
whose position is specified by row and column.
>>> pascal(0, 0)
1
>>> pascal(0, 5) # Empty entry; outside of Pascal's Triangle
0
>>> pascal(3, 2) # Row 3 (1 3 3 1), Column 2
3
>>> pascal(4, 2) # Row 4 (1 4 6 4 1), Column 2
6
"""
"*** YOUR CODE HERE ***"
if column == 0 or row == column:
return 1
elif row < column:
return 0
else:
return pascal(row - 1, column - 1) + pascal(row - 1, column)
Q5: Repeated, repeated
def repeated(f, n):
"""Returns a function that takes in an integer and computes
the nth application of f on that integer.
Implement using recursion!
>>> add_three = repeated(lambda x: x + 1, 3)
>>> add_three(5)
8
>>> square = lambda x: x ** 2
>>> repeated(square, 2)(5) # square(square(5))
625
>>> repeated(square, 4)(5) # square(square(square(square(5))))
152587890625
>>> repeated(square, 0)(5)
5
>>> from construct_check import check
>>> # ban iteration
>>> check(HW_SOURCE_FILE, 'repeated',
... ['For', 'While'])
True
"""
"*** YOUR CODE HERE ***"
if n == 0:
return lambda x: x
elif n == 1:
return f
else:
return compose1(f, repeated(f, n - 1))