需要帮助理解这个双递归

时间:2016-07-12 21:28:59

标签: java recursion

我有一些代码

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

}

生成传递的名称字符串的所有可能组合。代码工作,我理解递归如何在某种程度上工作,但双递归调用真的让我感到困惑。我已经看了很长时间了,而且我很难理解它正在做什么。任何有关这方面的帮助将不胜感激。我已经尝试过调试,但我仍然无法理解它。

1 个答案:

答案 0 :(得分:1)

你可以将递归想象成一堆执行。

  1. buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName, result);被调用并添加到堆栈顶部

  2. 如果if(nameIndex >= nameArray.length)匹配,我们会查看堆栈上是否还有元素,如果是,我们将其中一个向下并进入第3步,否则我们就完成了。如果条件不匹配,则在步骤1中进行exectution

  3. 我们从buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName, result);的调用返回,因此继续调用添加到堆栈顶部的buildNameChoicesHelper(nameArray, nameIndex + 1,firstName, lastName + "." + nameArray[nameIndex], result);,从1开始

  4. 您的示例的callstack如下所示:

    //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