[英]Converting a function with two recursive calls into an interative function
我有一個函數有兩個遞歸調用,我試圖將其轉換為迭代函數。 我已經弄明白我可以通過一個電話很容易地做到這一點,但我無法弄清楚如何合並另一個電話。
功能:
def specialMultiplication(n):
if n < 2:
return 1
return n * specialMultiplication(n-1) * specialMultiplication(n-2)
如果我只有其中一個,那將非常容易:
def specialMult(n, mult = 1):
while n > 1:
(n, mult) = (n-1, n * mult) # Or n-2 for the second one
return mult
我只是無法弄清楚如何添加第二個調用以獲得正確的答案。 謝謝!
如果您不介意更改算法的結構,可以從最低值開始以自下而上的方式計算值。
def specialMultiplication(max_n):
a = b = 1
for n in range(1, max_n+1):
a, b = b, a*b*n
return b
使用輔助“待辦事項列表”將遞歸轉換為迭代函數:
def specialMultiplication(n):
to_process = []
result = 1
if n >= 2:
to_process.append(n)
while to_process: # while list is not empty
n = to_process.pop()
result *= n
if n >= 3:
to_process.append(n-1)
if n >= 4:
to_process.append(n-2)
return result
to_process
) n >= 2
,則在列表中添加n
to_process
不為空時,從列表中彈出項目,乘以結果 n-1 < 2
,則不執行“左”操作(不附加到工作清單) n-2 < 2
,則不執行“正確”操作(不附加到工作清單) 該方法具有消耗較少堆棧的優點。 我已經針對從1到25的值的遞歸版本檢查了結果並且它們是相等的。
注意它仍然很慢,因為復雜度是O(2^n)
所以它從n=30
開始變得非常慢(當n增加1時,時間加倍)。 我的筆記本電腦在12秒內計算出n=28
。
我在執行泛洪填充算法時成功使用此方法來修復堆棧溢出問題: 致命的Python錯誤:無法從堆棧溢出中恢復。 在洪水填充期間,但是這里的Blcknght答案更適應,因為它重新思考從一開始就計算它的方式。
OP的函數具有與Fibonacci和Lucas函數相同的遞歸結構,只是f0,f1和g的值不同:
f(0) = f0
f(1) = f1
f(n) = g(f(n-2), f(n-1), n)
這是遞歸關系的一個例子。 這是一般解決方案的迭代版本,以n步計算f(n)。 它對應於自下而上的尾遞歸。
def f(n):
if not isinstance(n, int): # Can be loosened a bit
raise TypeError('Input must be an int') # Can be more informative
if n < 0:
raise ValueError('Input must be non-negative')
if n == 0:
return f0
i, fi_1, fi = 1, f0, f1 # invariant: fi_1, fi = f(i-1), f(i)
while i < n:
i += 1
fi_1, fi = fi, g(fi_1, fi, n) # restore invariant for new i
return fi
Blckknight的答案是這個的簡化版本
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.