試圖教我的大腦發現頭與尾遞回。這是尾遞回嗎?遞回陳述句在末尾,但是總變數中也存盤了一些資料,這讓我感到困惑。
def visible_tree_node(root:Node) -> int:
def dfs(root:Node,current_max:int) -> int:
if not root:
return 0
total = 0
if root.val >= current_max:
current_max = root.val
total =1
total = dfs(root.left,current_max)
total = dfs(root.right,current_max)
return total
return dfs(root,-float('inf'))
uj5u.com熱心網友回復:
dfs呼入處于尾部visible_tree_node位置。該呼叫,并且只有該呼叫,可以通過
類似地,while回圈將編譯為最后有條件跳轉的塊。如果某些條件為真,則條件跳轉將回傳到回圈的開頭,如果為假,則繼續。
a
while b:
c
d

在 CFG 形式中,如果呼叫位于函式的最后,則呼叫位于尾部位置。我們可以用 Python 結構遞回地定義這些規則,如下所示。我最熟悉static single-assignment,所以我將在下面的示例中使用它。
- 函式的最后一行位于尾部位置,因為它后面沒有指令。
return出于類似的原因,處于尾部位置的陳述句的運算式本身也處于尾部位置。- 如果
if陳述句位于尾部位置,則if分支的最后一行以及任何elif或else分支都處于尾部位置。一個if(andelseandelif) 導致 CFG 分裂,如果它處于尾部位置,則分裂不會重新組合在一起;它會簡單地回傳給呼叫者,因此就 CFG 分析而言,我們仍處于函式的末尾。 - 如果回圈 (
for或) 位于尾部位置,則此回圈內while緊跟在 a 后面的任何陳述句都處于尾部位置。break這個很復雜,所以一些優化器可能會錯過它。Abreakinside a loop 將在 SSA 中編譯為goto回圈的結尾,如果回圈的結尾也是函式的結尾(即尾部位置),那么之前的東西break也是如此。 - 如果一個
try ... finally塊出現在尾部位置,則該finally部分的最后一行也處于尾部位置。
一些構造永遠不會處于尾部位置。例如,a 的內部with永遠不會處于尾部位置,因為with必須在塊完成后運行代碼。這些規則并不全面;根據各種 Python 構造如何編譯為 CFG,它們正是我現在可以在現場提出的。一個全面的串列需要對不適合此答案范圍的控制流進行更詳細的分析。
我以前從未聽說過“頭部遞回”這個詞。我想它可以通過基本上與上述規則雙重的規則來定義為“遞回是第一件事”,但這聽起來不是一個非常有用的概念(因為不可能優化)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/528345.html
標籤:Python递归
