2011-03-15 67 views
1

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

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)

答案是passps

我不没有CLUE他们是如何到达那里的......

如果有人能帮助我处理这件事情,我会非常感激。在互联网上的其他地方,他们只解释阶乘 - 简单的例子。不知道会发生什么,如果你把它叫做char first = mystery (blah);两次,然后再次char second = mystery (blah);

+1

那么,这种方法的意图是什么呢?但它是如何工作的就像其他任何形式的递归一样。 – 2011-03-15 12:58:13

+6

这条线是否正确? 'char second = mystery(s,n/s,m * 2 +1);'当试图用一个字符串除n时,'n/s'部分是否会通过编译错误? – justkt 2011-03-15 12:59:01

+0

这些数字对我来说没有意义。为什么你有'n/s'而不是'n/2'? – 2011-03-15 13:00:44

回答

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)后面写下该字母。

5

因此,你已经知道recursion的例子以及它如何使用。

也许你缺少的是为什么递归工作。为了理解这个,你需要知道当一个方法被调用时会发生什么。熟悉call stack

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

1

按照@ jleedev的回答所述,手“执行”是一项有用的练习,尤其是如果您以前从未做过。

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

不要太担心它对你来说是个谜,mystery函数实际上是做什么的。它显然被设计为难以理解。 (除了神秘之外,我看不出有任何意义......)除了神秘之外,大多数递归函数都会做一些有用的事情,并且会更容易理解......带着经验...

0

对于每一次递归都有两件事要考虑:

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