Java递归输出名称向前和向后

时间:2017-04-06 14:04:55

标签: java recursion

我很久以前在课堂上写了一个基本的递归问题,我正在努力记住我是如何得到打印的输出的。

它基本上打印出一个名称向前和向后。我理解它如何打印名称向前但我对它如何向后打印名称一无所知。我做了一个调试,一步一步看到正在发生的事情但无法理解名称打印前后索引如何减少。

public class CharRecursion 
{

public static void printName(String name, int index)
  {
    if(index > name.length() - 1)
    {
        return;
    }
    else
    {
        System.out.println(name.charAt(index));
        printName(name, index + 1);
        System.out.println(name.charAt(index));
    }
  }
public static void main(String[] args) 
  {
        printName("Brian", 0);
  }

}

输出为BriannairB

3 个答案:

答案 0 :(得分:2)

向后部分来自第二个System.out.println(name.charAt(index));声明。

只有在递归调用以递归方式结束时才会调用此函数,因此您最终使用反向字符串,查看后缀标记:

    System.out.println(name.charAt(index) + " - ");
    printName(name, index + 1);
    System.out.println(name.charAt(index) + " * ");

你得到:

B - 
r - 
i - 
a - 
n - 
n *
a *
i *
r *
B *

由于实际的通话顺序是:

printName(name,0)> printName(name,1)> printName(name,2)> printName(name,3)> printName(name,4)

解决第二个println语句的第一个电话将是printName(name, 4),然后是printName(name, 3)等等。打印顺序将变为:

System.out.println(name.charAt(4) + " * ");
System.out.println(name.charAt(3) + " * ");
System.out.println(name.charAt(2) + " * ");
System.out.println(name.charAt(1) + " * ");
System.out.println(name.charAt(0) + " * ");

答案 1 :(得分:1)

理解这一点的方法是使用笔和纸手动完成它。 我不能足够强烈地推荐你实际使用真实的纸张,直到你明白发生了什么为止。

使用一张纸记录输出。

每次调用printName()时都使用新的单独纸张。

main()开始。当您看到printName("Brian", 0)时,这是开始新纸张的信号。在表格的顶部,写下输入:name - "Brian", index = 0

现在您已进入printName(),所以请逐步完成。 0小于"Brian".length() - 1,因此您可以跳至else块:

  • System.out.println(name.charAt(index)); - 请在输出表上写下"Brian".charAt(0)的结果:B

  • printName(name, index + 1) -- since you're seeing printName()again, take another sheet of paper, write the inputs name =" Brian",index = 1`位于顶部,将此位置放在上一张工作表的顶部

继续以这种方式工作,你将不断添加到你的纸叠。这直接类似于Java维护的执行堆栈;这与您在堆栈跟踪中看到的堆栈相同。

最终,您将到达index = "Brian".length() -1的位置,以便您返回。当您看到return时,请移除您正在处理的工作表,将其拧紧并将其扔进垃圾箱。运行时已完成此方法的调用。继续下面的工作表,你离开的地方。您现在处于第二个System.out.println(name.charAt(index));。所以在输出表上写下这个字符。

当你完成后,你会发现你已经写过" BriannairB"在你的输出表上,你应该更好地理解递归。

每张纸代表堆栈框架。请记住:

  • 在执行期间的给定时刻,只有最顶层的堆栈帧是"可见"就执行而言。
  • 局部变量和参数存储在堆栈帧中。在执行的某个时刻,当前堆栈帧中index的值将为3。这对下面的堆栈框架中index的值没有影响 - 这是一个完全独立的存储空间,当2框架结束并弹出时仍然是3堆栈。

但是,一旦掌握了这一点,你就可以在更多的声明中看到它"水平。 printName("Brian",0)做了什么?

它打印" B"然后printName("Brian", 1)然后" B"。

我认为这个实现稍微容易理解:

  void printName(String s) {
      if(s.length() > 0) {
           System.out.println(s.charAt(0));
           printName(s.substring(1));
           System.out.println(s.charAt(0));
      }
  }

因此,printName("Brian")B然后printName("rian")然后B

或者从最深的堆栈开始:

printName("")什么都不写。

因此printName("n")n然后printName("")然后n - nn

答案 2 :(得分:0)

以下是程序的执行顺序。程序调用{​​{1}}函数递归,在每次调用之前执行第一个public class A { public int one { get; set; } public int two { get; set; } public static implicit operator A(B v) { return new A { one = v.one, two = v.two }; } } 。当索引到达printName("Brian",index)时,函数调用开始返回,每次返回后执行第二个System.out.println(name.charAt(index));