【问题标题】:Tracing the recursion跟踪递归
【发布时间】:2016-04-13 19:12:43
【问题描述】:

我在网上看到了这段代码,我想跟踪递归。我设法做到了:

A 
AB
ABC

我认为我做错了。

这是代码:

public class Test
{
    public static void main(String[] args)  
    {
        printAll("ABC", 0, new StringBuffer());
        //      Outputs
        //      ---------
        //      A
        //      AB
        //      ABC
        //      AC
        //      B
        //      BC    
        //      C
    }

    private static void printAll(String str,int start, StringBuffer sb)
    {
        for(int i=start; i< str.length(); i++)
        {
            sb.append(str.charAt(i));
            System.out.println(sb);
            printAll(str, i+1, sb);
            sb.setLength(sb.length()-1);
        }
    }
}

【问题讨论】:

  • 你认为你哪里出错了?还有比如何做更具体的问题吗?如果我们知道您希望代码做什么,就更容易纠正您的理解。
  • 我只需要知道怎么做。跟踪此代码的递归的方法。

标签: java recursion


【解决方案1】:

这是一个简单的“展开”:

输入序列是ABC,所以这样:

for(int i=start; i< str.length(); i++)
{
    sb.append(str.charAt(i));
    System.out.println(sb);
    printAll(str, i+1, sb);
    sb.setLength(sb.length()-1);
}

展开至此,start 设置为 0:

sb.append("ABC".charAt(0));
System.out.println(sb);
printAll("ABC", 1, sb); //Recursive call
sb.setLength(sb.length()-1);
sb.append("ABC".charAt(1));
System.out.println(sb);
printAll("ABC", 2, sb); //Recursive call
sb.setLength(sb.length()-1);
sb.append("ABC".charAt(2));
System.out.println(sb);
printAll("ABC", 3, sb); //Recursive call
sb.setLength(sb.length()-1);

鉴于长度为3,我们到此结束。但现在我们还需要展开递归调用:

sb.append("ABC".charAt(0)); // sb="A"
System.out.println(sb);
//Entering recursive call, start=1
    sb.append("ABC".charAt(1));  // sb="AB"
    System.out.println(sb);

    //Entering recursive call, start=2
        sb.append("ABC".charAt(2));  // sb="ABC"
        System.out.println(sb);
        //Enter recursive call, start=3
            // 3 is not less than "ABC".length(), so we leave immediately
        //Exit recursive call
        sb.setLength(sb.length()-1);  // sb="AB"
    //Exit recursive call

    sb.setLength(sb.length()-1);  // sb="A"
    sb.append("ABC".charAt(2));  // sb="AC"
    System.out.println(sb);
    //Enter recursive call, start=3
        // 3 is not less than "ABC".length(), so we leave immediately
    //Exit recursive call
    sb.setLength(sb.length()-1);  // sb="A"
//Exit recursive call

sb.setLength(sb.length()-1);  // sb=""
sb.append("ABC".charAt(1));  // sb="B"
System.out.println(sb);

//Entering recursive call, start=2
    sb.append("ABC".charAt(2));  // sb="BC"
    System.out.println(sb);
    //Enter recursive call, start=3
        // 3 is not less than "ABC".length(), so we leave immediately
    //Exit recursive call
    sb.setLength(sb.length()-1);  // sb="B"
//Exit recursive call

sb.setLength(sb.length()-1);  // sb=""
sb.append("ABC".charAt(2));  // sb="C"
System.out.println(sb);

//Enter recursive call, start=3
    // 3 is not less than "ABC".length(), so we leave immediately
//Exit recursive call

sb.setLength(sb.length()-1);  // sb=""

有了这个完全“展开”,我们可以将它粘贴到 main 函数中并执行它,看到预期的结果。您还可以像我在 cmets 中一样,了解代码在每个步骤中的作用。

【讨论】:

  • 虽然我需要问为什么 sb.append("ABC".charAt(2));来了?
  • 最后一个?这是最终 for 循环的第一次调用。
  • 不,后一秒退出递归调用
  • 此时你已经深入到递归的一帧。该函数调用是使用start=1 进行的。之前的sb.append 调用(第4 行)是在第一个递归调用的第一个循环中进行的。您所指的调用是第一个递归调用的第二个循环,其中start 已递增到 2。
  • 我不知道有这样的资源,但你所要做的就是用函数本身替换对其他函数的调用,并填写变量是什么,这样你就可以看到实际的序列是执行。
猜你喜欢
  • 2022-01-23
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
相关资源
最近更新 更多