簡體   English   中英

如何將這個非尾遞歸函數轉換為循環或尾遞歸版本?

[英]How to convert this non-tail-recursion function to a loop or a tail-recursion version?

我一直很好奇這個。 對於人來說,創建一個非尾遞歸函數以獲得復雜的東西真的非常容易和優雅,但速度非常慢並且很容易達到Python遞歸的極限:

def moves_three(n, ini=0, med=1, des=2):
    '''give a int -> return a list '''
    if n == 1:
        return ((ini,des),)
    return moves_three(n-1, ini=ini, med=des, des=med) + \
           ((ini, des),) + \
           moves_three(n-1, ini=med, med=ini, des=des)

if __name__ == '__main__':
    moves_three(100) # may be after several hours you can see the result.
    len(moves_three(10000)) 

那么,如何將moves_three改為尾遞歸一個或一個循環(更好)? 更重要的是,有沒有論文可以談論這個? 謝謝。

即使使用迭代形式,這也不會更快。 問題不在於遞歸限制; 你仍然比遞歸限制低一個數量級。 問題是輸出的大小是O(2^n) 對於n=100 ,您必須構建一個大約1000億億元素的元組。 你如何建造它並不重要; 你永遠不會完成。

如果你想將它轉換為迭代,那么可以通過使用顯式堆棧而不是調用堆棧來管理狀態來完成:

def moves_three(n, a=0, b=1, c=2):
    first_entry = True
    stack = [(first_entry, n, a, b, c)]
    output = []
    while stack:
        first_entry, n1, a1, b1, c1 = stack.pop()
        if n1 == 1:
            output.append((a1, c1))
        elif first_entry:
            stack.append((False, n1, a1, b1, c1))
            stack.append((True, n1-1, a1, c1, b1))
        else:
            output.append((a1, c1))
            stack.append((True, n1-1, b1, a1, c1))
    return tuple(output)

令人困惑,不是嗎? 堆棧上的元組(True, n, a, b, c)表示使用參數n, a, b, c進入函數調用。 元組(False, n, a, b, c)表示在moves_three(n-1, a, c, b)結束后返回(True, n, a, b, c)調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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