【问题标题】:Automatically refactor a loop into a recursive method?自动将循环重构为递归方法?
【发布时间】:2010-10-10 03:01:11
【问题描述】:

您知道有一种工具可以自动将具有单个循环的方法重构为递归方法,最好是在 Java 中吗?

这是用于教学目的。

【问题讨论】:

  • 奇数。通常你想换一种方式,递归到迭代。
  • 有趣的问题,你有解决这个问题的算法描述吗?

标签: java refactoring recursion loops


【解决方案1】:

我认为不存在这样的工具,因为通常重构旨在提高性能,而不是降低性能(使用递归方法而不是循环时就是这种情况)。如果是出于教学目的,为什么不让学生创建可以做到这一点的工具呢?这样,他们可以同时学习递归和解析。

我不知道递归是否可以自动化,但这是转换的样子。为了演示,让我们以伪代码的形式使用一个通用的 for 循环:

loopFunc() // method (could return a value or not)
{
    for (initialization ; // Sets the context
         test ;           // Test continuation wrt the context
         counting_exp     // Update the context after each iteration
        ) 
    { 
        loop_body
    }
}

循环由四部分组成:initialization,初始化上下文(通常是变量); test,这是一个布尔表达式,用于检查循环是否完成; counting_exp,即每次迭代后执行的语句;最后是loop_body,表示每次迭代执行的操作。

这个方法的递归版本应该被分解成两部分:一个用于初始化,另一个用于实际执行循环:

recFunc()
{
    initialization        // Sets the context
    innerRecFunc(context) // We need to pass the context to the inner function
}

innerRecFunc(context)
{
    if not test then return // could return a value
    else
    {
        loop_body             // Can update context
        counting_exp          // Can update context
        innerRecFunc(context) // Recursive call (note tail-recursion)
    }
}

我没有充分考虑这个问题,无法 100% 确定这在所有情况下都有效,但对于简单的循环,这应该是正确的。当然,这种转换可以很容易地适应其他类型的循环(while、do while)。

【讨论】:

  • 但是每一次重构都有对等和相反的重构。
【解决方案2】:

我不完全确定这在一般意义上是否可行,因为在我看来它像是 the halting problem 的变体。

【讨论】:

  • 但是每个迭代算法都可以转换为递归算法,反之亦然。还是您在谈论问题的“自动”部分?
  • 通常无法确定两个程序是否相同,但可以有一组保持等价的转换。如果我们忽略可能的堆栈溢出,将算法从迭代更改为递归应该可以工作。
  • 这可能在一般意义上是不可取的(想想副作用),但你只需要支持一个有用的子集。
  • mmyers:是的,这就是我所指的。对于人类来说,停止问题也不是问题,因为您可以通过一些动手分析和 oogling 很容易地确定特定程序是否停止。
【解决方案3】:

如果您这样做是出于教学目的,我认为您可以在非常有限的情况下避免这样做。那你能不能写点东西呢

myMethod() {
  // startcode
  for (init,cond,incr) {
    // loopcode
  }
  //endcode
}

并将其转换为

myMethod() {
  //startcode
  init;
  recursive(value);
  //endcode
}
recursive(value) {
  if (!cond) {
    return
  } else {
    //loopcode
    incr;
    recursive(value);
}

我相信你可以自己整理出伪代码。

【讨论】:

    猜你喜欢
    • 2020-10-01
    • 2015-01-08
    • 2017-10-26
    • 2017-02-28
    • 2012-12-29
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多