Java 识别可转换为递归方法的方法

Java 识别可转换为递归方法的方法,java,recursion,Java,Recursion,我一直在四处寻找来练习我的递归,但是我在codingBat和其他一些方面已经没有练习的问题了。如果你有更多的建议,请随意评论 我的问题是即使您必须或可以更改参数,您如何确定何时可以将方法简单地转换为递归方法? 需要的递归方法的元素将是一个视为递归结束的必需基本情况,以及循环或不循环的原因(恢复为基本情况条件)。我是否遗漏了递归方法的其他重要方面 下面是我发现的一个递归方法的示例(但还没有解决递归问题)。它来自codingBat,我没有要求任何人更正我的代码。我发现这只是一个可以转换的方法的例子。

我一直在四处寻找来练习我的递归,但是我在codingBat和其他一些方面已经没有练习的问题了。如果你有更多的建议,请随意评论

我的问题是即使您必须或可以更改参数,您如何确定何时可以将方法简单地转换为递归方法?

需要的递归方法的元素将是一个视为递归结束的必需基本情况,以及循环或不循环的原因(恢复为基本情况条件)。我是否遗漏了递归方法的其他重要方面

下面是我发现的一个递归方法的示例(但还没有解决递归问题)。它来自codingBat,我没有要求任何人更正我的代码。我发现这只是一个可以转换的方法的例子。我会弄明白的

当答案出现时进行编辑。由于混淆,删除了示例。 编写递归方法时要注意的要求:

  • 堆栈溢出错误
  • 所有包含循环的方法都可以递归,但是它可能不是实现的最佳选择
  • 递归方法对于要解决的问题应该是自然的

  • 基本上,递归可以模拟每个循环,因此您可以为几乎每个包含循环的方法创建一个递归方法——但是不能保证递归版本会完成(因为您的循环版本可能会使用状态缓存结果,而您的递归版本不会)甚至运行(因为您可能会得到一个
    堆栈溢出错误
    –多么合适)

    编辑:注意,即使使用直接递归可能导致堆栈溢出,也有一种技术可以解决这个问题,即(本文是针对python的,但也适用于Java8的lambdas)


    编辑2:还请注意,迭代解和递归解之间的关系是由于-猜想造成的。

    基本上,递归可以模拟每个循环,因此您可以为几乎每个包含循环的方法创建一个递归方法–但是不能保证递归版本会完成(因为循环版本可能会使用状态缓存结果,而递归版本则不会)甚至运行(因为您可能会得到一个
    StackOverflowError
    –多么合适)

    编辑:注意,即使使用直接递归可能导致堆栈溢出,也有一种技术可以解决这个问题,即(本文是针对python的,但也适用于Java8的lambdas)


    编辑2:还请注意,迭代解和递归解之间的关系是由于-猜想造成的。

    将循环转换为递归总是可能的(但不是相反):

    比如说

    for(int i = 0; i < length; ++i)
        doStuffOn(i);
    
    function doStuffRec(int i, int length) {
        if(i < length) { // recursionCondition
            doStuffOn(i); // body
            int nextI = i + 1; // step
            doStuffRec(nextI, length);
        }
    }
    // calling level (initialisation of i)
    doStuffRec(0, length);
    
    for(int i=0;i
    将循环转换为递归始终是可能的(但不是相反):

    比如说

    for(int i = 0; i < length; ++i)
        doStuffOn(i);
    
    function doStuffRec(int i, int length) {
        if(i < length) { // recursionCondition
            doStuffOn(i); // body
            int nextI = i + 1; // step
            doStuffRec(nextI, length);
        }
    }
    // calling level (initialisation of i)
    doStuffRec(0, length);
    
    for(int i=0;i
    基本上,您可以编写以递归或迭代方式循环的每个方法。您只需要一个条件来停止循环

    有时,递归方法比迭代方法更容易实现,但需要注意的是运行时

    long fibonacci(long Parameter) {
      if(Parameter <=1)
        return 1;
      else
        return fibonacci(Parameter-1)+fibonacci(Parameter-2);
    }
    
    这里的运行时复杂性是线性的,这意味着运行时随着输入线性增长。(IIRC甚至有一个带有公式的解决方案,所以运行时是O(1),几乎是瞬间的)


    因此,在某些情况下,递归函数比iterativ更容易编写,有时情况正好相反。但使用递归函数时,您必须小心运行时!

    基本上,您可以编写以递归或迭代方式循环的每个方法。您只需要一个条件来停止循环

    有时,递归方法比迭代方法更容易实现,但需要注意的是运行时

    long fibonacci(long Parameter) {
      if(Parameter <=1)
        return 1;
      else
        return fibonacci(Parameter-1)+fibonacci(Parameter-2);
    }
    
    这里的运行时复杂性是线性的,这意味着运行时随着输入线性增长。(IIRC甚至有一个带有公式的解决方案,所以运行时是O(1),几乎是瞬间的)


    因此,在某些情况下,递归函数比iterativ编写起来更自然,有时情况正好相反。但使用递归函数时,您必须小心运行时!

    即使在您的示例中,递归方法的效率也不如基于StringBuilder的普通方法。只有当递归是自然函数时,才应使用递归解决问题的方法,并不是因为您可以使用它。每个方法都可以转换为递归方法。有些语言,如Haskell和Prolog,没有其他循环机制。即使在您的示例中,递归方法的效率也不如基于StringBuilder的普通方法。只有当递归是解决问题的自然方法时,才应该使用递归m、 不是因为你可以使用它。每个方法都可以在递归中转换。有些语言,如Haskell和Prolog,没有其他的循环机制。通常需要状态来建模或缓存可以通过递归计算的结果-每个循环都可以转换为递归形式这基本上就是我要寻找的,还有直觉我知道有些无法重复的方法不应该因为堆栈溢出。@JacobHein,如果这回答了你的问题,请接受答案。我现在不太确定如何选择答案。所有答案都说相同的t