简体   繁体   English

在递归的基本情况下返回 None 的目的是否只是用作填充物,然后自然而然地执行调用堆栈中的顶级递归调用?

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

I am solving a recursion problem, where I am given an array of integers and asked to return the powerset of it.我正在解决一个递归问题,在那里我得到一个整数数组并要求返回它的幂集。

eg powerset of [1,2,3] is [[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]例如 [1,2,3] 的幂集是 [[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2, 3]]]

Here is the recursive code that does it:这是执行此操作的递归代码:

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

While I do understand what is happening for the most part, my questions are:虽然我确实了解大部分情况,但我的问题是:

  1. when we get to the base case idx<0, this means the idx pointer points outside of the array, and we don't want to call array[idx], but my question is- do we return the empty set "[[]]" just as a filler, so that the top recursive call on the recursion stack gets executed next?当我们到达基本情况 idx<0 时,这意味着 idx 指针指向数组之外,我们不想调用 array[idx],但我的问题是 - 我们是否返回空集“[[] ]" 只是作为填充符,以便接下来执行递归堆栈上的顶部递归调用? Otherwise what does this do?不然这有什么作用?

  2. This might be a tallish order, but can someone explain with respect to the example [1,2,3] how the recursive call runs?这可能是一个很高的顺序,但是有人可以解释一下示例 [1,2,3] 递归调用是如何运行的吗? Here is my understanding;这是我的理解;

  • We start with the pointer idx pointing at 3, so ele=3, we then initialise a subset called subset that holds the powerset of [1,2]我们从指向 3 的指针 idx 开始,所以 ele=3,然后我们初始化一个叫做子集的子集,它保存了 [1,2] 的幂集

  • Here is where I am confused, and struggling to see how the code pans out... Do we now go to the next batch of code which is the for loop?这就是我感到困惑的地方,并且正在努力查看代码如何运行……我们现在是否转到下一批代码,即 for 循环? Or do we calculate the powerset of [1,2]?或者我们计算 [1,2] 的幂集?

Adding print to the start and end of a recursive call is a useful way to visualize how it works.在递归调用的开始和结束处添加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

prints:印刷:

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]]

Note that 0 and None need to be handled differently, which is why you need to use idx is None instead of not idx !请注意, 0None需要以不同的方式处理,这就是为什么您需要使用idx is None而不是not idx

As written, the function returns the power set of array[:idx+1] if it's passed an explicit index.如所写,如果传递了显式索引,该函数将返回array[:idx+1]的幂集。

The test idx < 0 is really testing idx == -1 , as other negative values should never occur.测试idx < 0实际上是在测试idx == -1 ,因为其他负值不应该出现。 In this case, the function should compute the power set of the empty set, which is a set that contains one element: the empty set.在这种情况下,函数应该计算空集的幂集,这是一个包含一个元素的集合:空集。 The set containing the empty set is represented by [[]] .包含空集的集由[[]]

My impression is that you're trying to think of the recursive function as a loop written in a confusing way.我的印象是您试图将递归函数视为以令人困惑的方式编写的循环。 You should instead just think of it as a function that computes something – in this case, a power set – and happens to use itself as a library function (in a way that always terminates).相反,您应该把它看作是一个计算某些东西的函数——在这种情况下,是一个幂集——并且碰巧将自己用作库函数(以一种总是终止的方式)。

Given a nonempty set S, which contains an element x, and a way to compute the power set of the smaller set S\\{x}, how do you get the power set of S?给定一个包含元素 x 的非空集合 S,以及一种计算较小集合 S\\{x} 的幂集的方法,您如何获得 S 的幂集? Answer: for each set in the power set of S\\{x}, return two sets: that set, and that set with x added to it.答案:对于 S\\{x} 的幂集中的每个集合,返回两个集合:那个集合,以及添加了 x 的那个集合。 That's what this code does.这就是这段代码的作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM