2012-10-12 27 views
2

的所有訂購的數字我有這樣的代碼來打印所有的「命令」一個位數的號碼,給定的數字解釋這個遞歸算法打印位數

數量(如果數量是xyz,那麼它是有序的iff x < y < z),

該代碼工作,但我無法理解for循環中使用的邏輯。這是遞歸,但如果任何人都可以更多地解釋,那會很好。

class OrderedNumbers{ 

    public static void main(String args[]){ 
     printOrdered(0,0,3); // 3 digit numbers 
    } 

    private static void printOrdered(int number, int prev, int n) { 

     if(n==0){ 
      System.out.println(number); 
      return; 
     } 

     for(int i=(prev+1); i<(11-n); i++){ 
      printOrdered(number*10 + i, i, n-1) ; 
     } 

    } 

} 
+0

假設你沒有寫這段代碼(否則你會理解它),你在哪裏找到這段代碼? – Bernard

+0

我在一些網站上以僞代碼的形式找到它。我不記得該網站。我試圖通過運行和調試來理解它,但是不能。 – rgamber

+0

@noahz,感謝您的編輯。 – rgamber

回答

3

看看參數。

  • number是迄今爲止組成的編號。在添加最後一位數字之前,我們將該數字乘以十,以便再追加一位數字。
  • prev是前一位數字的值。此後,for循環將啓動一個循環,從而確保編號內的數字是有序的。
  • n是尚未附加的位數。當達到零時,達到最大遞歸深度並打印數字。我們還使用n來計算for循環中的上限。最後一位數字不能大於9,第二位數字不能大於8,依此類推。 YOu可以從n=1的條件讀取i<10,即i<=9這一事實看出這一點。

遞歸調用會將前一個數字再加上一個數字,該數字的值確保後面的數字更大,剩餘數字的數量減少一個。

+0

感謝您的解釋。這很有幫助! – rgamber

1

該函數的最後一個參數控制函數自身調用的次數。當printOrdered在循環中調用自身時,它將當前的數字和移動乘以10(將數字移到左邊的一個位置)。然後它添加i(放在一個地方)。當n=0該功能知道所有必要的數字已被添加,因此它返回(打印)當前的數字。

i從比以前的數字多了一個運行(否則它不會是一個有序號)11-n,這是說,在n位的數字,最顯著的數字只能作爲11-n一樣大。考慮3位數字的最大訂購號碼789。數百個地方永遠不能超過7個,你明白爲什麼?

總之

  • number是當前(也可能不完全)訂購數量
  • prev是加入number
  • n最後一位數字是需要添加的位數到number
  • i循環遍及所有可能被添加到number在下一個地方的數字。它必須大於最後一位數字,但仍然留有剩餘數字的空間,一旦printOrdered被再次調用,剩餘數字將被添加。
1

首先,注意,許多是「有序」,最左邊的數字必須小於(11-n),其中n是位數。如果您使用3位數字,則會訂購「789」,但如果最左邊的數字是8,然後是9,則不會留下較高的數字以填充最右邊的位置。 (所有其他數字也是如此。)

在第一次調用printOrdered時,for循環會生成所有可用於最左邊位置的有效數字。對於每個這樣的數字,遞歸調用會生成可以在第二個最左邊位置使用的所有有效數字,依此類推。 number是一個累加器,它建立要打印的數字,而n倒計時直到要打印的數字已經完全建立。 prev被命名爲誤導性;它會出現在這一個的左側的數字。對於要「定購」的號碼,您只能生成高於的數字,而不是prev,這就是爲什麼循環變量初始化爲prev + 1

+0

感謝您的解釋! – rgamber