2012-12-06 118 views
0

我正在開發一個項目。我發現這個關於Interwebz上排列的代碼。我想用它作爲編寫我自己的代碼的基礎。但是,我不太瞭解代碼中發生了什麼。任何人都可以幫我解釋一下代碼的作用嗎?有人可以解釋這段代碼嗎?置換代碼

public void permutations(String prefix, String s) { 
    int n = s.length(); 
    if (n == 0) 
     System.out.println(prefix); 
    else { 
     for(int i = 0; i < n; i++){ 
      permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n)); 
     } 
    } 
} 
+5

它被稱爲遞歸。 – jlordo

回答

1

permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));

其實,這個置換算法是使用

Switching current character with ith character. 

假設的想法,我們有一個字符串abc。所以,它的排列是:

abc, acb, bac, bca, cab, cba

我們可以發現,acb只是切換bcabc前綴a。而bca只是在bac中切換ca,前綴爲b

然後我們只是使用相同的想法遞歸地解決排列問題。

2

permutations方法採用字符串prefix和String s作爲其參數。 int類型n正在設置爲字符串s的長度。 (字符串的長度是它包含的字符數)。

現在我們繼續討論if - else聲明。 if聲明說,如果s的長度爲0,即s是空白字符串並且不包含任何信息,那麼我們只是將字符串prefix打印到控制檯。然後該方法將跳過else部件並在permutations方法之後執行代碼。

如果if語句的條件不具備,我們要運行else聲明說,在字符串s每一個字符,我們將追加(添加),該角色在prefix結束,所以例如,如果prefix最初是「hello」,而字符是'U',那麼我們會得到prefix爲「helloU」。在我們完成追加s中的所有字符後,我們將使用結果作爲新的prefix字符串。

對於其他參數,字符串s,我們將從字符0(包含)到位置i(不包括)處的字符參與字符串的一部分。請注意,字符串索引從0開始並上升到(字符串的長度 - 1)。我們還從位置i + 1(含)的字符中取出字符串的一部分到字符串s中的最後一個字符。我們將使用此結果作爲新的s字符串。

然後我們將再次調用該方法,然後如果滿足else條件,該方法將再次用新定義的字符串執行。這將持續循環,直到else條件未滿足,此時該方法將停止運行,並且我們將轉到下一部分代碼(如果存在)。

+0

如果您需要我澄清任何事情,請不要猶豫,問我。 – hologram

1

這是一些非常令人困惑的代碼,原因有二:

  1. prefix說法:你應該調用在第一個參數爲空字符串此功能,例如permutations("", "ab")打印的所有(兩個)排列"ab"
  2. 在第二個參數中遞歸調用s.substring(0, i) + s.substring(i+1, n):注意java的String.substring(x,y)而不是包括第y個字符。所以這相當於通過s刪除了第y個字符。

現在想想,你通過for循環步驟會發生什麼:第一個參數成爲"""a"連接在一起,即"a",第二個參數變得s與刪除的第一個字符,即"b"。在下一個遞歸子調用中,prefix變爲"ab",第二個參數變爲空字符串""。因此,基本情況n == 0受到打擊,我們打印結果"ab"

現在我們繼續下一個for循環迭代,i == 1。現在我們在遞歸subcall的第一個參數中傳遞"b",在第二個參數中傳遞"a"。在下一個遞歸subcall prefix變成"ba"s.length是0,所以基地案件再次:打印"ba"

它很聰明,但不可思議。

1

p(String prefix, String s)需要s中的1個字符,並將其添加到prefix並遞歸繼續,直到s爲空。

s.charAt(i), s.substring(0, i) + s.substring(i+1, n)部分從s中提取字符。 假設s = "Magic!"i = 3然後charAt(i) = 'i',s.substring(0, i) = "Mag"s.substring(i+1, n) = c!"Magic!發生iMagc!。下一次在i = 4的循環中,將導致c + Magi!。由於它對s中的每個字符都會這樣做,因此每個字符都將在遞歸步驟之一的前面。

調用層次是這樣的

       /p("ab", "c") - "abc" 
       /- p("a", "bc") x 
       /    \ p("ac", "b") - "acb" 
      /
      /    /p("ba", "c") - "bac" 
p("", "abc") x ---- p("b", "ac") x 
       \     \ p("bc", "a") - "bca" 
       \ 
       \    /p("ca", "b") - "cab" 
       \- p("c", "ab") x 
            \ p("cb", "a") - "cba" 

       ^-- 1st for loop ^- 2nd for  ^- 3rd one prints 
相關問題