【问题标题】:Is recursion to iteration or vice versa algorithm exists?是否存在递归迭代或反之亦然算法?
【发布时间】:2012-09-16 19:02:15
【问题描述】:

是否存在具有最高效率输出和尾递归的迭代或反之递归算法?

首选语言是 C#。

例如:输入这个算法得到下一个简单的函数:

public static ulong Factorial(ulong n)
{
    return n == 0 ? 1 : n * Factorial(n - 1);
}

处理后返回如下:

public static ulong Factorial(ulong n)
{
    ulong result = 1;
    for (ulong i = 1; i <= n; i++)
        result = result * i;
    return result;
}

【问题讨论】:

  • 您是否需要一个代码转换器,它将特定语言的递归算法作为输入并返回该语言的迭代算法?
  • @KvanTT:这与您要使用的语言域严格相关。顺便说一句,与算法没有任何关系。如果我正确理解了这个问题,这就是代码的转换,保持它的语义。不要认为 CS 中还存在这样的工具。
  • @Michael Petrotta,是的。有很多描述如何手动转换它,但没有解释如何通过算法进行转换。为此,必须在开始时使用解析器。
  • 有一个从递归到迭代的简单重写,使用显式堆栈。但是您不能像上面的示例那样轻松地将一种算法重写为完全不同的算法。它可能适用于某些特殊情况,但可能不适用于一般情况。
  • 关于手动转换代码的算法,请查看how to rewrite a recursive method by using a stack?

标签: c# algorithm recursion iteration


【解决方案1】:

是的,总是可以从递归算法创建迭代版本。我不知道 C# 是否存在用于执行此操作的程序/代码重写器。这种技术已经得到很好的研究,你可以找到像From recursion to iteration: what are the optimizations? (pdf file)这样的一般参考。
最坏的情况是简单地“模拟”堆上的堆栈以保存函数的状态以供将来使用。最简单的情况可能是尾递归循环。有很多关于这个主题的文章。
另一方面,从通用迭代算法创建递归版本的研究较少,但它确实存在,

【讨论】:

    【解决方案2】:

    我唯一知道的是,使用stack 可以同样地将递归转换为非递归,因为它实际上是这样做的,你可以自己做。

    顺便说一句,你可能会想到一些无法转换为简单迭代的情况。

    【讨论】:

    • 是的,每个递归都可以转换为带有堆栈的迭代,这非常简单。但在许多情况下,转换为非堆栈版本是可能的(例如在阶乘和斐波那契数中),而且它更加有趣和复杂。
    【解决方案3】:

    我不知道进行这种转换的算法的简单通用实现,但是使用dynamic programming 方法优化递归算法是微不足道的,这些方法非常通用。

    例如,如果您在字典中缓存每个Factorial 调用的结果(来自n -> Factorial(n) 的映射),您将获得相等的算法复杂度到迭代的(但!只有时间复杂度。此方法使用更多内存)。请注意,简单地“模仿”您自己的堆栈不会在算法复杂性方面给您带来任何好处。

    缓存非常容易实现和应用,适用于各种算法。

    维基百科页面在您的示例算法上有一个特定的entry

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-25
      • 2011-02-08
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      • 2014-02-12
      相关资源
      最近更新 更多