簡體   English   中英

將具有兩個遞歸調用的函數轉換為交互函數

[英]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
  1. 創建工作清單( to_process
  2. 如果n >= 2 ,則在列表中添加n
  3. to_process不為空時,從列表中彈出項目,乘以結果
  4. 如果n-1 < 2 ,則不執行“左”操作(不附加到工作清單)
  5. 如果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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM