我想到了这一点,我明白了回报是如何运作的,但是一旦我进入递归,我想我比原先想象的要多一些。
假设我有一个计数函数,一个字符串弹出一个字符串的次数。
int frequency(char ch, string input, int pos) {
if (pos == inputString.length()) {
return 0;
}
if (inputString[pos] == ch) {
return 1 + frequency(ch, inputString, pos + 1);
}
else {
return frequency(ch, inputString, pos+1);
}
}
如果我要传递给它,字符串" Jeff"并寻找" f",它返回值2
。
那么,它如何知道何时停止?
return 0
是否会以返回类型int
结束任何方法?
如果是这样,为什么当 final 返回显示返回2
时,它仍会返回0
的值?
答案 0 :(得分:3)
最后一次回归
return 0;
只是在递归期间调用函数的最后一次。这需要在某个时刻停止递归。对于之前的调用,执行其他一个返回语句,例如:
return 1 + frequency(ch, inputString, pos + 1);
因此将0加到1以及任何先前的递归结果。
PS: 只要函数return语句再次调用该函数,递归就会继续。只有当返回只是返回一些东西(没有再次调用fucntion)时,递归才会停止。
这是一个更简单的例子,它计算所有整数之和为N:
int calcSum(int N){
if ( N == 1 ) return 1; // recursion stops here
return N + calcSum( N-1 ); // otherwise continue to add up
}
一个函数中的多个return语句对递归并不特殊。该函数只在它遇到的第一个返回时返回。
答案 1 :(得分:2)
那么,它如何知道何时停止?
当递归调用函数中的特定分支不再添加递归调用时,它将停止,并且调用堆栈将按照发出调用的相反顺序(LIFO)清除返回值。这是在这里完成的:
if (inputString[pos] == ch) {
return 1 + frequency(ch, inputString, pos + 1);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
else {
return frequency(ch, inputString, pos+1);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
任何其他分支递归调用该函数并在调用堆栈中逐步调低:
return 0;
0
是否以任何返回类型为int的方法结束?
是的,它适用于任何可以使用2
- 如果是这样,为什么在最后一次返回显示返回
0
时,它仍会返回return 1 + frequency(ch, inputString, pos + 1); // ^ the result of the operation will be saved on the stack when the call returns
的值?
因为递归调用结果的结果是在堆栈上累积的:
int frequency(char ch, string input) {
int result = 0;
for(int pos = 0; pos < input.size(); ++pos) {
if (input[pos] == ch) {
++result;
}
}
return result;
}
...并且您在驱动程序函数中看到(第一个)递归调用的最终结果。
顺便说一句,通过性能和内存使用来实现便宜得多的实现将是一个简单的循环。无论如何,线性时间行为没有任何缺点:DECLARE @names TABLE
(
Name varchar(20)
)
INSERT INTO @names
SELECT 'Tom'
INSERT INTO @names
SELECT 'John'
INSERT INTO @names
SELECT 'Chris'
INSERT INTO @names
SELECT 'Ann'
INSERT INTO @names
SELECT 'Ben'
select Name, case when Name = 'John' then 1 else 0 end AS IsTopRow
from @names
order by IsTopRow DESC, Name
答案 2 :(得分:0)
将递归调用视为一堆函数调用。在某些时候它可能会命中return 0;
这意味着堆栈上的一个函数调用已完成。因此弹出堆栈上的元素。当堆栈为空时,函数的 final 返回。