Java 这个递归是如何工作的
这段代码反转传递给它的字符串参数。我知道字符串是不可变的。我似乎不明白发生了什么事。它将返回的反向字符串存储在何处Java 这个递归是如何工作的,java,recursion,Java,Recursion,这段代码反转传递给它的字符串参数。我知道字符串是不可变的。我似乎不明白发生了什么事。它将返回的反向字符串存储在何处 public static String reverseRecursively(String str) { //base case to handle one char string and empty string if (str.length() < 2) { return str; } return reverseRe
public static String reverseRecursively(String str) {
//base case to handle one char string and empty string
if (str.length() < 2) {
return str;
}
return reverseRecursively(str.substring(1)) + str.charAt(0);
}
publicstaticstring反向递归(stringstr){
//处理一个字符字符串和空字符串的基本大小写
如果(str.length()<2){
返回str;
}
反向递归返回(str.substring(1))+str.charAt(0);
}
您的反向递归(str.substring(1))+str.charAt(0)
每次调用时都会创建一个新的字符串
对象
它将返回的反向字符串存储在何处
public static String reverseRecursively(String str) {
//base case to handle one char string and empty string
if (str.length() < 2) {
return str;
}
return reverseRecursively(str.substring(1)) + str.charAt(0);
}
正如该方法所示,它递归地调用自己。每次调用它时,它都会将条目添加到调用堆栈中。因此,如果您关心存储这些“中间”结果的神奇之处,请阅读调用堆栈的工作原理 下面是一个调用图,说明了数据流:
每个调用都返回一个字符串副本,第一个字符放在最后,其余字符由进一步调用处理。对这些字符串的引用存储在堆栈上,该堆栈随着每次调用而增长(需要更多的堆栈空间来处理更长的字符串)。您是否尝试过将结果写在纸上,或使用调试器处理它?如果在返回局部变量之前将最终表达式赋给它,您可能会发现它更容易一些。@JonSkeet是的,我已经这样做了。它在每次传递时删除字符串的第一个字符,并最终返回反向的string@erictesting-有一部分“+str.charAt(0)”。。。试着按照Jon对3个字符的字符串的建议,在纸上单步执行代码…@JonSkeet我想他想知道每个中间递归调用的值存储在哪里。事实上这是个好问题,这就是为什么我抹去了他的反对票。我尽了最大努力回答,但我相信你或其他人可以回答得更详细。@KyleM谢谢,至少有人理解我的观点。这个图表和OP的代码,正是尾部调用所不具备的。他的递归调用不在尾部位置,因为在返回其结果之前,他向其添加了
str.charAt(0)
。至于图,如果这是一个尾部调用,“返回值”对于每个递归调用都是完全相同的。非尾部调用没有错,但是维基百科关于尾部调用的文章与这个问题完全无关。