【问题标题】:How can I make a recursive version of my iterative method?如何制作迭代方法的递归版本?
【发布时间】:2011-02-01 15:35:43
【问题描述】:

我正在尝试用 Java 编写一个递归函数来打印数字 1 到 n。 (n 是您发送函数的参数。)迭代解决方案非常简单:

public static void printNumbers(int n){
    for(int i = 1; i <= n; i++){
         System.out.println(i);
         i++;
    }

作为一名新程序员,我很难弄清楚这种方法的递归版本如何工作。

【问题讨论】:

  • 告诉我们你目前的尝试

标签: java recursion iteration


【解决方案1】:

您正在使用从 i=1 迭代到 n 的 for 循环。由于您想通过递归来执行此操作,并且传递 n 而不是 i n 更容易,我们只是将整个事情颠倒过来,所以我们将 n 倒数到 @ 987654327@。为了保持打印的顺序,我们先调用递归函数,执行完后打印数字:

public static void printNumbers ( int n )
{
    if ( n > 0 )
    {
        printNumbers( n - 1 ); // n - 2, if the "i++" within the for loop is intended
        System.out.println( n );
    }
}

对于简单的迭代 -> 递归转换,很容易将循环更改为如下格式:

public static void printNumbers ( int n )
{
    int i = 1;
    while ( i <= n )
    {
        System.out.println( i );
        i++; // i += 2, if the "i++" within the for loop is intended
    }
}

现在您可以轻松地将其转换为递归函数:

public static void printNumbers ( int n, int i )
{
    if ( i <= n )
    {
        System.out.println( i );
        i++; // i += 2, if the "i++" within the for loop is intended
        printNumbers( n, i );
    }
}

其他都是优化。

【讨论】:

  • 谢谢,第一个解决方案正是我想要的。
【解决方案2】:

递归版本需要两个参数(ni),因此将其设为辅助非公共方法,然后从公共方法中调用它即可开始递归:

static void auxPrintNumbers(int n, int i){
    if(i <= n) {
        System.out.println(i);
        auxPrintNumbers(i + 1);
    }
}

public static void printNumbers(int n){
    auxPrintNumbers(n, 1);
}

【讨论】:

  • 这看起来是正确的。但是,您能想出一种不使用辅助方法的方法吗?
  • @user247679,@Rafael 对此有一个想法,尽管它与您的代码和我的代码略有不同/不同,因为它总是打印至少一行,即使 n 开头是 0 (但这是可以修复的)。但是我的版本是尾递归的,有朝一日可能会允许智能 Java 编译器对其进行优化(唉,不是今天)...;-)。
【解决方案3】:

你的迭代版本有一些问题:你迭代i 两次,在for 语句中然后在循环结束时再次;你也应该让i &lt; n 成为你循环的结束条件。

要回答您的问题,显然递归函数必须打印出当前号码,如果当前号码尚未达到 n,则再次调用自身 - 所以它必须采用当前号码(我们称之为 @ 987654324@ 在迭代版本中)作为参数 - 或者类需要将其作为实例变量保存,但我会坚持使用参数。

【讨论】:

  • 你说得对,我在迭代方法中将 i 递增了两次,感谢您指出这一点。但是,结束条件确实应该是 i
【解决方案4】:

根据打印从 1 到 n 的每个奇数的函数,递归函数应如下所示:

public static void printNumbersRecursive(int n)
{
  if (n % 2 == 0) printNumbersRecursive(n - 1);
  else if (n > 0)
    printNumbersRecursive(n - 2);
  System.out.println(n);
}

如果这是一个错误并且您想要打印从 1 到 n 的每个数字,那么:

public static void printNumbersRecursive(int n)
{
  if (n > 0)
    printNumbersRecursive(n - 1);
  System.out.println(n);
}

【讨论】:

    【解决方案5】:

    课堂版(只是为了好玩):

    class R {
    
      private final int n;
    
      public R (final int n) {
        if (n <= 0) {
          throw new IllegalArgumentException("n must be positive");
        }
        this.n = n;
      }
    
      @Override
      public String toString () {
        final StringBuilder sb = new StringBuilder();
        if (this.n > 1) {
          sb.append(new R(this.n - 1).toString());
        }
        sb.append(this.n).append(" ");
        return sb.toString();
      }
    }
    

    用作:

    System.out.println(new R(10));
    

    【讨论】:

      【解决方案6】:
      public static void printNumbers(int n){
         if( n > 1 ){
            printNumbers(n - 1);
         }
         System.out.println(n);
      }
      

      此函数递归调用自身,直到达到 n = 1。从此时起,所有值都以正确的顺序打印:1、2、3、...

      【讨论】:

        猜你喜欢
        • 2010-09-19
        • 1970-01-01
        • 2011-01-18
        • 2010-10-02
        • 1970-01-01
        • 2021-12-24
        • 2014-10-13
        • 2016-07-21
        • 1970-01-01
        相关资源
        最近更新 更多