簡體   English   中英

如何制作迭代方法的遞歸版本?

[英]How can I make a recursive version of my iterative method?

我正在嘗試用Java編寫一個遞歸函數,該遞歸函數可打印數字1到n。 (n是發送函數的參數。)迭代解決方案非常簡單:

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

作為一個新程序員,我在弄清楚該方法的遞歸版本如何工作時遇到了麻煩。

您正在使用從i=1迭代到n的for循環。 由於您希望通過遞歸進行此操作,並且更容易傳遞n而不是i n ,因此我們將整個過程都反轉了,因此我們將n遞減為1 為了保持打印順序,我們首先調用遞歸函數,並在執行后打印數字:

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 );
    }
}

其他一切都是優化。

遞歸版本需要兩個參數( ni ),因此使其成為輔助的非公共方法,只需從public方法調用它即可開始遞歸操作:

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);
}

您的迭代版本存在一些問題:您正在for語句中迭代i兩次,然后在循環結束時再次迭代; 你也應該讓i < n是循環的結束條件。

要回答您的問題,顯然遞歸函數將必須打印出當前數字,如果當前數字尚未達到n,請再次調用自身-因此它必須使用當前數字(在迭代中稱為i版本)作為參數-或類需要將其作為實例變量保存,但我會堅持使用該參數。

根據輸出從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);
}

一個類版本(只是為了好玩):

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));
public static void printNumbers(int n){
   if( n > 1 ){
      printNumbers(n - 1);
   }
   System.out.println(n);
}

此函數遞歸調用自身,直到達到n =1。從這一點開始,所有值均以正確的順序打印:1、2、3,...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM