递归 - 它做了什么

时间:2011-03-15 12:54:16

标签: java recursion

我的智慧结束了...我理解递归的更简单的例子,但是当它变得棘手时我没有线索。这是一个例子。如果有人能说出它的作用,我会很高兴的。编译器做了什么......

public static char mystery(String s, int n, int m)
{
if (n==1) return s.charAt(m);

char first = mystery(s, n/2, m*2);
char second = mystery(s, n/2, m*2 +1);

System.out.print(first + " " + second + " ");

return first; 
}

调用方法时打印的内容: 神秘(“fredpass”,5,1)

答案是p s s p s

我没有CLUE如何到达那里......

如果有人可以帮我解决这个问题,真的会很感激。在互联网上的其他地方,他们只解释了阶乘 - 简单的例子。不确定如果您在char first = mystery ( blah );中再调用两次,然后再次char second = mystery ( blah );

,会发生什么

4 个答案:

答案 0 :(得分:5)

因此,您已经了解recursion的示例以及如何使用它。

或许你缺少的是为什么递归有效。为了理解这一点,您需要知道调用方法时会发生什么。熟悉call stack

就逻辑上发生的事情而言,您应该只考虑按顺序“遍历”代码。当您以递归方式调用方法时,它将返回结果并继续执行,就像在任何其他过程代码中一样。但是,每个方法调用都有自己的scope of variables,它只在递归的特定调用中有效。

答案 1 :(得分:5)

只需手动追踪电话:

mystery(5, 1)
    first = mystery(2, 2)
        first = mystery(1, 4) = 'p'
        second = mystery(1, 5) = 'a'
    second = mystery(2, 3)
        ...

等等。给自己足够的纸张来绘制调用堆栈的完整画面,函数调用的状态和局部变量。例如,在我的图片中最里面的调用打印“p a”后,它返回'p',所以我会在mystery(2, 2)之后写下该字母。

答案 2 :(得分:1)

按照@ jleedev的回答中描述的手“执行”是一项有用的练习,特别是如果你以前从未这样做过。

另一种方法是在Java调试器的控制下运行代码,并在检查调用堆栈/局部变量时单步执行。这不容易出错,但如果你做得太快,你可能会错过实际发生的重要细节。

不要太担心mystery功能实际上对你来说是个谜。它显然是难以理解的。 (而且我看不到它的任何意义......除了神秘之外。)你可能遇到的大多数递归函数都会做一些有用的东西,并且更容易理解......有经验......

答案 3 :(得分:0)

对于每次递归,有两件事需要考虑

  1. 每个递归方法都应该有一个基本情况。
  2. 每次递归都应该朝着这个基本情况发展