【问题标题】:Convert recursion to iteration when there are loops in the function当函数中有循环时,将递归转换为迭代
【发布时间】:2021-01-03 14:00:43
【问题描述】:

我正在将我们代码库中的一些递归调用转换为迭代。感谢this blogthis question,这非常简单。但是,有以下模式(作为一个最小的例子),这让我很难过。它基本上给出了m位置中n数字的n^m排列(重复)(这里是n=4m=3):

def f (i, arr):
    if i < len(arr):
        for j in [2,3,5,8]:
            arr[i] = j
            f(i+1, arr)
    else:
        print(arr)

f(0, [0,0,0])

哪个输出:

[2, 2, 2]
[2, 2, 3]
[2, 2, 5]
...
[8, 8, 3]
[8, 8, 5]
[8, 8, 8]

根据this discussion,这应该是可能的。如果有人可以分享一些关于如何进行此转换的指导,那就太好了?

【问题讨论】:

  • 你能把函数修改为使用循环,而只使用递归吗?那会更容易转换。

标签: python algorithm recursion iteration enumeration


【解决方案1】:

从代码中退后一步,考虑一下您要在此处生成什么模式可能会有所帮助。例如,想象一下,每个插槽有十个数字可供选择,它们是 0、1、2、...、9。在这种情况下,您所做的基本上是从 000 开始向上计数,直到你最终达到 999。你是怎么做到的?嗯:

  • 如果最后一位不是 9,则加一。大功告成。
  • 否则,数字为 9。将其回滚到 0,然后移动到前一个数字。

在你的情况下,是数字 2、3、5 和 8,但这并不重要。

你可以把它翻译成一个很好的过程来解决一个更一般的问题,列出所有写出从 k 个选项列表中提取的 n 个符号的方法:

def list_all_options(length, options):
    # Initially, pick the first option in each slot. This array stores
    # indices rather than values.
    curr = [0] * length
    
    while True:
        # Print what we have, mapping from indices to values.
        print([options[index] for index in curr])
        
        # Roll over all copies of the last digit from the end, backing
        # up as we go.
        pos = len(curr) - 1
        while pos >= 0 and curr[pos] == len(options) - 1:
            curr[pos] = 0
            pos -= 1
        
        # If we rolled all digits, we're done!
        if pos == -1: break
        
        # Otherwise, increment this digit.
        curr[pos] += 1

【讨论】:

  • 非常感谢,这是思考问题的好方法。
猜你喜欢
  • 2015-01-08
  • 1970-01-01
  • 2020-08-08
  • 2015-05-30
相关资源
最近更新 更多