2016-07-12 97 views
0

我有一些代碼需要幫助理解這個雙遞歸

public class NameGenerator { 
public static void main (String[] args) 
{ 
    List<String> result = new ArrayList<String>(); 
    buildNameChoices("von.del.smith", result); 
    System.out.println(result); 
} 
public static void buildNameChoicesHelper(String[] nameArray, int nameIndex, 
    String firstName, String lastName, List<String> result) { 

    if(nameIndex >= nameArray.length) { 
     if(lastName.length() > 0) { 
      result.add(firstName + lastName); 
     } 
    } 
    else { 
     System.out.println("Calling first buildNameChoices"); 
     buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName, result); 
     System.out.println("Calling second buildNameChoices"); 
     buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName + "." + nameArray[nameIndex], result); 
    } 
} 
public static void buildNameChoices(String nameStr, List<String> result) { 
    String[] nameArray = nameStr.split("\\.", -1); 
    for(int i = 0; i < nameArray.length; i++) { 
     System.out.println("Inside for loop"); 
     buildNameChoicesHelper(nameArray, i + 1, nameArray[i], "", result); 
    } 
} 

}

生成一個名稱字符串,它傳遞的所有可能的組合。代碼有效,我理解遞歸如何在某個級別上工作,但雙遞歸調用真的讓我困惑。我一直在研究它很長一段時間,而且我很難完全掌握它在做什麼。任何幫助,將不勝感激。我試過通過它進行調試,但是我仍然不能真正理解它。

+0

究竟是什麼,你不明白?雙遞歸的概念?或者爲什麼這個特定的案例有效 – Abaddon666

+0

幾乎是整個概念。我真的不明白什麼時候第二個叫。它是否在第一個之後?或者是第一個叫基本案例,然後是第二個叫? – jordaniac89

+0

嘗試看看[this](http://stackoverflow.com/questions/19217565/understanding-double-recursion)這是一個雙遞歸的解釋。 – Abaddon666

回答

1

您可以將遞歸想象爲執行堆棧。

  1. buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName, result);被調用,並添加ontop的

  2. 如果if(nameIndex >= nameArray.length)匹配我們來看看,如果有在堆棧上仍然元素,如果是這樣,我們去一個向下和步驟3中的堆棧,否則我們是完了。如果條件不匹配在步驟exectution前進1

  3. 我們從buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName, result);呼叫返回,因此繼續進行呼叫,其ontop的堆疊的加入buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName + "." + nameArray[nameIndex], result);,從1

調用棧爲開始您的示例如下所示:

//execution 1 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "2", firstName: "von", lastName: "", result: "[]"); 

stack = [execution1]; 

//execution 2 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "3", firstName: "von", lastName: "", result: "[]"); 

stack = [execution1, execution2]; 

// nameIndex >= nameArray.length -> step 2 -> step3 
stack = [execution1]; 

// execution 3 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "3", firstName: "von", lastName + "." + nameArray[nameIndex]: ".smith", result: "[]"); 

stack = [execution1, execution3]; 

// nameIndex >= nameArray.length -> step 2 -> step3 
stack = [execution1]; 

//execution 4 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "2", firstName: "von", lastName + "." + nameArray[nameIndex]: ".del", result: "[von.smith]"); 

stack = [execution1,execution4]; 


// exectution 5 
// we are back at step 1 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "3", firstName: "von", lastName: ".del", result: "[von.smith]"); 

stack = [execution1,execution4,execution5]; 

// nameIndex >= nameArray.length -> step 2 -> step3  
stack = [execution1,execution4]; 

// execution 6 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "3", firstName: "von", lastName + "." + nameArray[nameIndex]: ".del.smith", result: "[von.smith, von.del]"); 

stack = [execution1,execution4,execution6]; 

// nameIndex >= nameArray.length -> step 2 -> step3  
stack = [execution1,execution4]; 

// execution 7 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "3", firstName: "del", lastName: "", result: "[von.smith, von.del, von.del.smith]"); 

stack = [execution1,execution4,execution7]; 

// nameIndex >= nameArray.length -> step 2 -> step3 
stack = [execution1]; 

// execution 8 
buildNameChoicesHelper(nameArray: [von, del, smith],nameIndex: "3", firstName: "del", lastName + "." + nameArray[nameIndex]: ".smith", result: "[von.smith, von.del, von.del.smith]"); 

stack = [execution1, execution8]; 

//1 and 8 both terminate 
+0

這實際上有很大幫助。我認爲當有多個等待執行的堆棧幀時,很容易產生困惑。 – jordaniac89

+0

雖然有一個簡單的問題。我看到第二個遞歸方法在執行3時被調用,索引仍然是3,就像它在第一個中一樣。爲什麼不是4? – jordaniac89

+0

這實際上是我的錯,我會糾正堆棧 – Abaddon666