当前位置: 首页 > news >正文

C++获取字符串最后一个单词长度的多种方法

问题描述

给定一个由多个单词组成的句子,每个单词由大小写字母混合构成,单词间使用单个空格分隔。要求输出最后一个单词的长度。

约束条件:

  • 每个单词非空
  • 总字符长度不超过 103103
  • 单词间使用单个空格分隔

示例:

1

2

3

4

输入:HelloNowcoder

输出:13

输入:A B C D

输出:1

解法一:从后向前遍历法(推荐)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#include <iostream>

#include <string>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

intlen = 0;

inti = str.size() - 1;

// 跳过末尾可能的空格(虽然题目说没有,但增加鲁棒性)

while(i >= 0 && str[i] ==' ') i--;

// 计算最后一个单词的长度

while(i >= 0 && str[i] !=' ') {

len++;

i--;

}

cout << len << endl;

return0;

}

算法分析

时间复杂度:O(n)

最坏情况下需要遍历整个字符串

空间复杂度:O(1)

只使用了常数个额外变量

优点:

  1. 高效:只需要一次遍历
  2. 节省空间:不需要额外存储
  3. 鲁棒性好:能处理末尾有空格的情况

解法二:使用rfind方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#include <iostream>

#include <string>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

// 从后向前查找最后一个空格的位置

size_tpos = str.rfind(' ');

if(pos == string::npos) {

// 没有空格,整个字符串就是一个单词

cout << str.size() << endl;

}else{

// 计算最后一个单词的长度

cout << str.size() - pos - 1 << endl;

}

return0;

}

关键点说明

  • rfind(' '): 从字符串末尾开始查找空格
  • string::npos: 表示未找到,值为-1(但类型为size_t,所以是最大无符号数)
  • 注意处理只有一个单词的情况

解法三:使用stringstream分割

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <iostream>

#include <string>

#include <sstream>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

stringstream ss(str);

string word, last_word;

// 读取所有单词,最后一个存储在last_word中

while(ss >> word) {

last_word = word;

}

cout << last_word.size() << endl;

return0;

}

算法特点

优点:

  1. 代码简洁易读
  2. 自动处理多余空格
  3. 容易扩展(如需要处理所有单词)

缺点:

  1. 需要额外的字符串拷贝
  2. 使用stringstream有额外开销
  3. 需要存储最后一个单词的完整副本

解法四:双指针法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <iostream>

#include <string>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

intright = str.size() - 1;

// 右指针:跳过末尾空格

while(right >= 0 && str[right] ==' ') right--;

intleft = right;

// 左指针:找到单词开头

while(left >= 0 && str[left] !=' ') left--;

// 计算长度

cout << right - left << endl;

return0;

}

算法性能对比

方法时间复杂度空间复杂度优点缺点
从后向前遍历O(n)O(1)效率高,内存少需要手动处理边界
rfind方法O(n)O(1)代码简洁需要处理npos
stringstreamO(n)O(n)自动处理空格额外开销大
双指针法O(n)O(1)思路清晰需要两个指针

边界条件处理

1. 空字符串

1

2

3

4

5

// 在从后向前遍历法中

if(str.empty()) {

cout << 0 << endl;

return0;

}

2. 全是空格

1

2

3

4

5

// 在从后向前遍历法中,第一个while循环后i可能为-1

if(i < 0) {

cout << 0 << endl;

return0;

}

3. 末尾有多个空格

1

2

// 所有方法都应该处理这种情况

// 解法一和四已经通过while循环处理

扩展问题

1. 获取倒数第二个单词的长度

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include <iostream>

#include <string>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

intcount = 0;

inti = str.size() - 1;

// 跳过末尾空格

while(i >= 0 && str[i] ==' ') i--;

// 找倒数第一个单词

while(i >= 0 && str[i] !=' ') i--;

// 跳过单词间的空格

while(i >= 0 && str[i] ==' ') i--;

// 找倒数第二个单词的末尾

intend = i;

while(i >= 0 && str[i] !=' ') i--;

cout << end - i << endl;

return0;

}

2. 统计句子中单词的数量

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <iostream>

#include <string>

#include <sstream>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

stringstream ss(str);

string word;

intcount = 0;

while(ss >> word) {

count++;

}

cout << count << endl;

return0;

}

3. 获取最长的单词

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include <iostream>

#include <string>

#include <sstream>

usingnamespacestd;

intmain() {

string str;

getline(cin, str);

stringstream ss(str);

string word, longest_word;

intmax_len = 0;

while(ss >> word) {

if(word.size() > max_len) {

max_len = word.size();

longest_word = word;

}

}

cout <<"最长单词: "<< longest_word <<", 长度: "<< max_len << endl;

return0;

}

实际应用场景

1. 命令行工具

1

2

// 实现类似Linux的wc命令,统计单词数

// 可以扩展为获取最后一行或最后一个单词

2. 文本编辑器

1

2

// 在代码编辑器中,获取光标所在单词的长度

// 用于自动补全或语法高亮

3. 日志分析

1

// 分析日志文件的最后一个状态码或错误信息

4. 自然语言处理

1

2

// 在NLP预处理中,获取句子的最后一个词

// 用于语言模型训练或情感分析

测试用例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

voidtest() {

// 测试用例集合

vector<pair<string,int>> test_cases = {

{"HelloNowcoder", 13},

{"A B C D", 1},

{"Hello World", 5},

{"a", 1},

{" ", 0},// 全是空格

{"hello ", 5},// 末尾有空格

{" hello", 5},// 开头有空格

{"multiple spaces between", 7},// 多个空格

{"", 0},// 空字符串

{"12345 67890", 5},

{"The quick brown fox jumps over the lazy dog", 3}

};

for(auto& test_case : test_cases) {

// 测试各个算法

cout <<"输入: \""<< test_case.first <<"\", 期望: "<< test_case.second << endl;

}

}

优化技巧

1. 使用引用避免拷贝

1

2

3

4

// 在处理大字符串时,使用const引用

voidprocessString(conststring& str) {

// 处理逻辑

}

2. 预分配内存

1

2

// 如果知道最大长度,可以预分配

str.reserve(1000);// 根据题目约束

3. 使用C风格字符串

1

2

3

4

5

6

7

8

9

10

11

// 在性能关键场景,可以使用C风格字符串

intgetLastWordLength(constchar* str) {

intlen = 0;

inti =strlen(str) - 1;

while(i >= 0 && str[i] ==' ') i--;

while(i >= 0 && str[i] !=' ') {

len++;

i--;

}

returnlen;

}

常见错误

1. 忘记处理npos

1

2

3

// 错误示例

size_tpos = str.rfind(' ');

intlength = str.size() - pos - 1;// 当pos为npos时,计算错误

2. 未考虑末尾空格

1

2

3

4

5

// 错误示例

intpos = str.rfind(' ');

if(pos != -1) {

cout << str.size() - pos - 1 << endl;// 如果末尾有空格,结果错误

}

3. 越界访问

1

2

3

// 错误示例

inti = str.size() - 1;

while(str[i] ==' ') i--;// 如果字符串为空,i为-1,访问越界

总结

获取字符串最后一个单词的长度是一个基础的字符串处理问题,但它涉及了许多重要的编程概念:

  1. 字符串遍历技巧:从后向前遍历是解决此类问题的关键
  2. 边界条件处理:空字符串、空格、单个单词等情况都需要考虑
  3. 算法选择:根据具体需求选择最合适的算法
  4. 代码鲁棒性:处理各种异常输入情况

推荐方法:从后向前遍历法

  • 效率高,空间复杂度低
  • 代码清晰,易于理解
  • 鲁棒性好,能处理各种边界情况

掌握这个问题的解法不仅能帮助解决类似问题,还能提高字符串处理的基本功。在实际开发中,根据具体场景选择最合适的方法才是最重要的。


http://www.jsqmd.com/news/1336105/

相关文章:

  • ABAP屏幕设计:从SE51布局到流逻辑的完整开发指南
  • 楼盘漫游动画:让客户在5-20分钟里“走进”未来的家
  • 佛山管道疏通公司口碑**:2026年本地正规品牌综合对比与推荐 - 园子一号
  • Unity DOTS ECS架构实战:万鱼同屏性能优化与数据导向设计
  • 2026 上海房产分割律师收费标准,高性价比律师 / 团队怎么选推荐君澜孙青联系电话13681945561 - 孙青律师13681945561
  • 2026深圳家庭搬家全流程**指南:打包分类、楼层吊装、新家还原、预算测算完整手册 - 禧燕搬家
  • 小白程序员必看:收藏这份Data Agent进阶指南,轻松玩转大模型数据分析
  • GetQzonehistory:5分钟快速找回你的QQ空间青春记忆
  • 5个技巧掌握Buzz音频转录工具,工作效率提升300%
  • Windows 10登录失败:从紧急抢救到系统级修复的完整指南
  • 【制造业AI部署黄金72小时】:从PLC数据接入到MOM系统联动,一份经17家工厂验证的标准化实施Checklist
  • 高并发架构、AI硬件配置与智能系统开发实战解析
  • GlobeLand30全球地表覆盖数据:从下载到城市扩张分析的完整指南
  • 2026年近期地下室远红外防潮防霉系统实力企业推荐与选型指南 - 企业深度能力测评
  • AI Agent实战:从Agent Plan到Seedance 2.0的工程化探索
  • 2026 上海房产确权律师收费标准,高性价比律师 / 团队怎么选推荐君澜孙青联系电话13681945561 - 孙青律师13681945561
  • 网站建设确认单到底该怎么签才不吃亏?深度解析网站建设确认单的每一个细节与坑位
  • HC-06蓝牙模块从入门到实战:硬件连接、AT命令配置与Arduino编程全解析
  • 揭秘厦门市建设与管理局网站:查询办事指南与项目审批的全景指南
  • AI微博运营不是替代人,而是淘汰不会用AI的人——2024Q2行业人才能力图谱首发,你卡在第几层?
  • Congruence (Modular Congruence) – Basic Exercises with Answers
  • 夸克网盘自动化助手:智能转存与媒体库管理的终极解决方案
  • 2026深圳搬家避坑**合集:低价套路、隐形增项、黑搬家识别、定金退还完整实操方案 - 禧燕搬家
  • 2026年国内攀岩墙厂家行业权威评测:头部厂商实力榜单与选型指南
  • Unity粒子系统三步打造节日烟花特效:从基础爆炸到完整烟花秀
  • STM32-S266-TDS水质检测+红外感应+水量监测+保温常温+温度+灯光指示+定时提醒+定时开关+加热+防干烧+参数+OLED屏+声光提醒+(无线方式选择)-21(设计源文件+万字报告+讲解)(
  • DLMS/COSEM协议深度解析:从对象模型到安全实践
  • mcp-helm MCP 服务说明文档
  • DDS技术解析:从原理到实战,掌握现代信号源核心
  • 大语言模型(LLM)构建实战:从核心原理到RAG应用开发指南