将具有for循环的递归函数更改为迭代函数?

时间:2009-11-23 06:33:54

标签: recursion loops for-loop iteration

所以我有这个功能,我试图从递归算法转换为迭代算法。我甚至不确定我是否有正确的子问题,但这似乎以正确的方式确定我需要的东西,但是递归不能用于你需要使用动态编程所以我需要将它改为迭代自下而上或顶部动态编程。

基本的递归函数如下所示:

Recursion(i,j) {
    if(i > j) {
        return 0;
    }
    else {
        // This finds the maximum value for all possible
        // subproblems and returns that for this problem
        for(int x = i; x < j; x++) {
            if(some subsection i to x plus recursion(x+1,j) is > current max) {
                max = some subsection i to x plus recursion(x+1,j)
            }
        }  
    }
}

这是一般的想法,但由于递归通常没有for循环,我不确定如何将其转换为迭代。有没有人有任何想法?

2 个答案:

答案 0 :(得分:0)

你有一个递归函数,可以概括为:

recursive(i, j):
    if stopping condition:
        return value

    loop:
        if test current value involving recursive call passes:
            set value based on recursive call

   return value # this appears to be missing from your example

(我将在这里使用伪代码,以强调代码的结构而不是特定的实现)

你想把它变成纯粹的迭代方法。首先,在一般情况下准确描述这涉及到什么是好的,因为您似乎对此感兴趣。然后我们可以继续展平上面的伪代码。

现在扁平化原始递归函数非常简单。当您获得类似的代码时:

simple(i):
    if i has reached the limit: # stopping condition
        return value

    # body of method here

    return simple(i + 1) # recursive call

您可以快速看到递归调用将继续,直到i达到预定义的限制。发生这种情况时,将返回value。这种迭代形式是:

simple_iterative(start):
    for (i = start; i < limit; i++):
        # body here

    return value

这是有效的,因为递归调用构成了以下调用树:

simple(1)
  -> simple(2)
    -> simple(3)
      ...
        -> simple(N):
            return value

我会将调用树描述为一段字符串。它有一个开头,一个中间和一个结尾。不同的调用发生在字符串的不同点上。

这样的一串调用就像一个for循环 - 函数完成的所有工作都会传递给下一个调用,递归的最终结果就会被传回。 for循环版本只接受将传递给不同调用的值并在其上运行正文代码。

到目前为止简单!

现在你的方法在两个方面更复杂:

  • 有多个单独的语句进行递归调用
  • 这些陈述本身属于for循环

所以你的调用树是这样的:

recursive(i, j):
  for (v in 1, 2, ... N):
    -> first_recursive_call(i + v, j):
      -> ... inner calls ...
    -> potential second recursive call(i + v, j):
      -> ... inner calls ...

正如你所看到的,这根本不像一个字符串。相反,它实际上就像一棵树(或灌木丛),每次通话都会导致另外两次通话。在这一点上,实际上很难将其转变为完全迭代的函数。

这是因为循环和递归之间的基本关系。任何循环都可以重新表示为递归调用。然而,并非所有递归调用都可以转换为循环。

可以转换为循环的递归调用类称为原始递归。你的功能最初似乎超越了那个。如果是这种情况,那么你将无法将其转换为纯粹的迭代函数(实际上在函数中实现调用堆栈和类似函数)。

此视频解释了原始递归与以下基本递归类型之间的区别:

https://www.youtube.com/watch?v=i7sm9dzFtEI

我想补充一点,您的条件和分配给max的值似乎是相同的。如果是这种情况,那么您可以删除其中一个递归调用,允许您的函数成为循环中包含的原始递归的实例。如果你这样做,那么你可能会把它弄平。

答案 1 :(得分:-1)

除非尚未包含逻辑问题,否则应该没问题

for&amp;虽然在递归中没问题

确保在每种可能发生的情况下都返回