[英]Is the purpose of returning None in base case of recursion simply used as a filler, and then naturally the top recursive call in call stack executes?
我正在解決一個遞歸問題,在那里我得到一個整數數組並要求返回它的冪集。
例如 [1,2,3] 的冪集是 [[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2, 3]]]
這是執行此操作的遞歸代碼:
def powerset(array, idx = None):
if idx is None:
idx = len(array)-1
if idx <0:
return [[]]
ele = array[idx]
subset = powerset(array,idx-1)
for i in range(len(subset)):
currentSubset = subset[i]
subset.append(currentSubset + [ele])
return subset
雖然我確實了解大部分情況,但我的問題是:
當我們到達基本情況 idx<0 時,這意味着 idx 指針指向數組之外,我們不想調用 array[idx],但我的問題是 - 我們是否返回空集“[[] ]" 只是作為填充符,以便接下來執行遞歸堆棧上的頂部遞歸調用? 不然這有什么作用?
這可能是一個很高的順序,但是有人可以解釋一下示例 [1,2,3] 遞歸調用是如何運行的嗎? 這是我的理解;
我們從指向 3 的指針 idx 開始,所以 ele=3,然后我們初始化一個叫做子集的子集,它保存了 [1,2] 的冪集
這就是我感到困惑的地方,並且正在努力查看代碼如何運行……我們現在是否轉到下一批代碼,即 for 循環? 或者我們計算 [1,2] 的冪集?
在遞歸調用的開始和結束處添加print
是一種可視化其工作方式的有用方法。
def powerset(array, idx=None, indent=0):
trace = f"{' '*indent}powerset({array}, {idx})"
print(f"{trace}...")
if idx is None:
idx = len(array)-1
if idx < 0:
print(f"{trace} -> [[]]")
return [[]]
ele = array[idx]
subset = powerset(array, idx-1, indent+1)
for i in range(len(subset)):
subset.append(subset[i] + [ele])
print(f"{trace} -> {subset}")
return subset
印刷:
powerset([1, 2, 3], None)...
powerset([1, 2, 3], 1)...
powerset([1, 2, 3], 0)...
powerset([1, 2, 3], -1)...
powerset([1, 2, 3], -1) -> [[]]
powerset([1, 2, 3], 0) -> [[], [1]]
powerset([1, 2, 3], 1) -> [[], [1], [2], [1, 2]]
powerset([1, 2, 3], None) -> [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
請注意, 0
和None
需要以不同的方式處理,這就是為什么您需要使用idx is None
而不是not idx
!
如所寫,如果傳遞了顯式索引,該函數將返回array[:idx+1]
的冪集。
測試idx < 0
實際上是在測試idx == -1
,因為其他負值不應該出現。 在這種情況下,函數應該計算空集的冪集,這是一個包含一個元素的集合:空集。 包含空集的集由[[]]
。
我的印象是您試圖將遞歸函數視為以令人困惑的方式編寫的循環。 相反,您應該把它看作是一個計算某些東西的函數——在這種情況下,是一個冪集——並且碰巧將自己用作庫函數(以一種總是終止的方式)。
給定一個包含元素 x 的非空集合 S,以及一種計算較小集合 S\\{x} 的冪集的方法,您如何獲得 S 的冪集? 答案:對於 S\\{x} 的冪集中的每個集合,返回兩個集合:那個集合,以及添加了 x 的那個集合。 這就是這段代碼的作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.