首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在递归函数中计算返回结果?

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

Stack Overflow用户
提问于 2016-05-18 11:22:26
回答 3查看 2.3K关注 0票数 1

到目前为止,我认为我理解了返回是如何工作的,但是一旦我进入递归,我想我会比最初的想法更加迷失。

假设,我有一个用于计数的函数,一个字符在字符串中弹出多少次。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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的方法?
  • 如果是这样的话,为什么它仍然返回2的值,而最后的返回是返回0
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-18 11:25:47

最后的回报

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
return 0;

是在递归期间调用该函数的最后一次。这是在某个时候停止递归所必需的。对于执行最后一个返回语句之前的调用,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
return 1 + frequency(ch, inputString, pos + 1);

因此,0被加到递归的1和以前的任何结果中。

PS:只要函数返回语句再次调用该函数,递归就会继续。只有当返回只是返回某项内容(而不再次调用函数)时,递归才停止。

下面是一个更简单的例子,它计算到N的所有整数的和:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int calcSum(int N){

    if ( N == 1 ) return 1;          // recursion stops here

    return N + calcSum( N-1 );       // otherwise continue to add up 

}

一个函数中的多个返回语句并不是递归所特有的。该函数只在遇到的第一次返回时返回。

票数 3
EN

Stack Overflow用户

发布于 2016-05-18 11:47:28

那么,它怎么知道什么时候停止呢?

当不再从递归调用函数中的特定分支添加更多递归调用时,它将停止,调用堆栈将被清除,返回值与发出调用的顺序相反(LIFO )。就在这里完成了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (pos == inputString.length()) {
    return 0;
}

任何其他分支都递归地调用该函数,并在调用堆栈中迈出一步:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (inputString[pos] == ch) {
    return 1 + frequency(ch, inputString, pos + 1);
            // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
}
else {
    return frequency(ch, inputString, pos+1);
        // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
}

  • return 0;结束任何返回类型为int的方法吗?

是的,它适用于任何可以用0初始化的返回类型。

  • 如果是这样的话,为什么它仍然返回2的值,而最后的返回是返回0

因为递归调用结果的结果是在堆栈上累积的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   return 1 + frequency(ch, inputString, pos + 1);
//          ^ the result of the operation will be saved on the stack when the call returns

..。并在驱动程序函数中看到(第一次)递归调用的最终结果。

顺便说一句,通过性能和内存使用来实现成本低得多的实现将是一个简单的循环。不管怎么说,线性时间行为没有任何缺点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int frequency(char ch, string input) {
   int result = 0;
   for(int pos = 0; pos < input.size(); ++pos) {
        if (input[pos] == ch) {
           ++result;
        }
    }
    return result;
}
票数 2
EN

Stack Overflow用户

发布于 2016-05-18 11:29:51

将递归调用视为函数调用的堆栈。在某个时候,它可能会命中return 0;,这意味着堆栈上的一个函数调用已经完成。因此,将弹出堆栈上的一个元素。函数的最后返回发生在堆栈为空时。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37308418

复制
相关文章
[Leetcode][python]Word Break/Word Break II/单词拆分/单词拆分 II
给定一个目标字符串和一组字符串,判断目标字符串能否拆分成数个字符串,这些字符串都在给定的那组字符串中。
蛮三刀酱
2019/03/26
1.3K0
动态规划:单词拆分
题目链接:https://leetcode-cn.com/problems/word-break/
代码随想录
2021/02/26
8650
动态规划:单词拆分
139. 单词拆分
题目 /** * 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 * 说明: * 拆分时可以重复使用字典中的单词。 * 你可以假设字典中没有重复的单词。 * * 示例 1: * 输入: s = "leetcode", wordDict = ["leet", "code"] * 输出: true * 解释: 返回 true 因为 "le
名字是乱打的
2021/12/23
4280
139. 单词拆分
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
张伦聪zhangluncong
2022/10/26
2660
140. 单词拆分 II
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
张伦聪zhangluncong
2022/10/26
1730
LeetCode 0139. 单词拆分[动态规划详解]
给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
Yano_nankai
2021/04/12
5310
LeetCode 0139. 单词拆分[动态规划详解]
Leetcode 139. 单词拆分
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
zhipingChen
2019/06/19
9390
HDU 1247 字典树 拆分单词
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6381    Accepted Submission(s): 2378
csxiaoyao
2019/02/18
5200
LeetCode 0140. 单词拆分 II[动态规划详解]
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
Yano_nankai
2021/04/12
4390
LeetCode 0140. 单词拆分 II[动态规划详解]
LeetCode 139. 单词拆分(DP)
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
Michael阿明
2020/07/13
3880
LeetCode 139. 单词拆分(DP)
高频面试系列:单词拆分问题
读完本文,可以去力扣解决如下题目: 139. 单词拆分(中等) 140. 单词拆分II(困难)
labuladong
2022/09/01
6550
高频面试系列:单词拆分问题
Leetcode|完全背包|139. 单词拆分
1 动态规划(完全背包) 基于问题本身,先背包后物品的顺序比较方便,也好理解 class Solution { public: bool wordBreak(string s, vector<string>& wordDict) { int bagSize = s.size(); vector<bool> dp(bagSize + 1, false); dp[0] = true; for (int j = 1; j <= bagSi
SL_World
2021/09/18
3850
刷题第6篇:单词拆分
我们使用递归的方法。每当遍历到一个字典中的单词之后,记录下当前的索引值,然后继续向后遍历。如果遍历到最后一个字符,恰好连接前面的字符,属于字典中的单词,则将此分割方式记录下来。
鹏-程-万-里
2020/02/26
3580
Leetcode No.140 单词拆分 II(DFS)
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。 说明: 分隔时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。
week
2022/01/06
5780
​LeetCode刷题实战139:单词拆分
https://leetcode-cn.com/problems/word-break/
程序员小猿
2021/01/19
3960
Leetcode No.139 单词拆分(动态规划)
给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
week
2021/11/29
5420
Leetcode No.139 单词拆分(动态规划)
在ASP.NET 5中使用SignalR
题记:SignalR作为ASP.NET中进行Web实时双向通信的组件,在ASP.NET 5中也得到了同步发展。不过,用法和之前还是在细节上有所不同,而资料又相对稀少。本文就是一个简单的入门向导。 通过SignalR,开发人员可以在ASP.NET开发的Web应用中实现服务器和客户端的双向实时通信。服务器可以即时推送内容给在线的客户端。SignalR首选Web Sockets作为底层实现,针对非现代浏览器也可以回退到其他兼容技术。它的特性很丰富,支持链接管理、分组连接和授权控制等。 在ASP.NET 5时代,S
逸鹏
2018/04/10
3.3K0
在ASP.NET 5中使用SignalR
英语单词记忆法拆分2000个_usually拆分记忆
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
全栈程序员站长
2022/09/22
3160
Asp.net中文本框全选
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/105743.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/09
1.4K0
在 Linkerd 中实现流量拆分功能
在 Linkerd 中,金丝雀发布是通过流量拆分来管理的,这项功能允许你根据可动态配置的权重,将请求分配给不同的 Kubernetes 服务对象。虽然流量分割可以适用于任意的 Service 对象,但一般情况下是将一个 Service 的传入流量分给不同版本的 Service。
我是阳明
2022/09/29
1.1K0
在 Linkerd 中实现流量拆分功能

相似问题

使用vba在文本框中查找单词

11

使用Regex拆分单词

24

使用CSS拆分单词

60

在SQL Server中拆分单词

214

在camelCase javascript中拆分单词

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文