[英]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.