如何在递归函数中计算返回结果?

时间:2016-05-18 19:22:26

标签: c++ recursion return

我想到了这一点,我明白了回报是如何运作的,但是一旦我进入递归,我想我比原先想象的要多一些。

假设我有一个计数函数,一个字符串弹出一个字符串的次数。

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的值?

3 个答案:

答案 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 返回。