c++中如何实现字符串的按单词反转_c++双指针法反转逻辑【详解】
发布时间 - 2026-01-22 00:00:00 点击率:次必须用双指针而非std::reverse直接反转,因为后者会使单词内部字母翻转;双指针法通过整体反转、单词内反转、清理多余空格三步实现单词顺序反转且单词内字符不变,空间复杂度O(1)。
为什么要用双指针而不是 std::reverse
直接对整个字符串调用 std::reverse 会把单词内部字母也翻转,比如 "hello world" 变成 "dlrow olleh",而题目要的是单词顺序反转、单词内字符不变——即变成 "world hello"。所以必须先按空格切分逻辑,再逐段反转,双指针法正好在原地完成这个过程,不依赖额外容器(如 std::vector<:string>),空间复杂度控制在 O(1)(不计输入字符串本身)。
双指针法三步走:整体反转 + 单词内反转 + 清理多余空格
标准做法是三个阶段,缺一不

- 第一遍:用两个指针从首尾向中间,
std::swap整个字符串 —— 让单词顺序倒过来,但每个单词也反了 - 第二遍:扫描字符串,对每个连续非空格子串(即一个单词),用局部双指针把它再翻回来
- 第三遍:处理开头、结尾和中间多个空格的问题;若要求“单词间仅一个空格”,需额外原地压缩(否则输出含冗余空格)
注意:C++ 中 std::string 支持随机访问和修改,所以所有操作可原地进行;但若传入的是 const std::string&,需先拷贝一份可变副本。
std::string 原地反转单词顺序的完整实现
以下代码实现「单词顺序反转 + 单词内字符不变 + 单词间仅保留一个空格」,不含额外库依赖(除 和 ):
void reverseWords(std::string& s) {
// 步骤1:整体反转
std::reverse(s.begin(), s.end());
// 步骤2:逐个单词反转(跳过空格,定位每个单词区间)
int n = s.length();
int i = 0;
while (i zuojiankuohaophpcn n) {
if (s[i] != ' ') {
int j = i;
while (j zuojiankuohaophpcn n && s[j] != ' ') j++;
std::reverse(s.begin() + i, s.begin() + j);
i = j;
} else {
i++;
}
}
// 步骤3:原地去重空格(保留单词间单空格,删首尾)
int write = 0;
for (int read = 0; read zuojiankuohaophpcn n; ++read) {
if (s[read] != ' ') {
if (write != 0) s[write++] = ' '; // 单词间加空格(首个单词前不加)
while (read zuojiankuohaophpcn n && s[read] != ' ') {
s[write++] = s[read++];
}
}
}
s.resize(write);}
关键细节:std::reverse 是双向迭代器安全的,适用于 std::string::iterator;第三步中 write 指针控制实际写入位置,避免新建字符串;s.resize(write) 截断末尾冗余字符。
容易被忽略的边界情况
很多实现在线 OJ 上失败,不是逻辑错,而是漏了这些:
- 输入为空字符串
""或全空格(如" ")—— 第三步压缩后应为"",不能 crash - 单词间有多个连续空格(如
"a b")—— 必须压缩,否则第二步翻转后仍残留空格,影响第三步判断 - 使用
size_t做索引时,与负数比较(如i-- >= 0)会因无符号溢出导致死循环 - 调用
std::reverse前未检查区间有效性(如begin() + i >= begin() + j),虽通常安全,但在空单词逻辑里可能触发
最稳妥的做法是:所有索引用 int,每步都校验 i 和 j ,压缩空格前先做 s.erase(0, s.find_first_not_of(' ')) 类清理(但会破坏原地性)—— 所以还是推荐上面的三阶段写法。
# word
# go
# c++
# 为什么
# String
# const
# 字符串
# int
# 循环
# 指针
# 的是
# 第三步
# 多个
# 切分
# 但在
# 适用于
# 把它
# 要用
# 不含
# 会使
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
桂林网站制作公司有哪些,桂林马拉松怎么报名?
微信小程序 闭包写法详细介绍
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
JavaScript如何实现继承_有哪些常用方法
如何用JavaScript实现文本编辑器_光标和选区怎么处理
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
如何在腾讯云免费申请建站?
深圳网站制作的公司有哪些,dido官方网站?
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
Linux网络带宽限制_tc配置实践解析【教程】
Laravel distinct去重查询_Laravel Eloquent去重方法
制作企业网站建设方案,怎样建设一个公司网站?
如何用景安虚拟主机手机版绑定域名建站?
高性能网站服务器部署指南:稳定运行与安全配置优化方案
如何用虚拟主机快速搭建网站?详细步骤解析
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
如何在七牛云存储上搭建网站并设置自定义域名?
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
python中快速进行多个字符替换的方法小结
高防服务器如何保障网站安全无虞?
Laravel怎么实现验证码(Captcha)功能
如何在橙子建站中快速调整背景颜色?
如何挑选高效建站主机与优质域名?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
音响网站制作视频教程,隆霸音响官方网站?
零基础网站服务器架设实战:轻量应用与域名解析配置指南
Laravel如何记录自定义日志?(Log频道配置)
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
黑客入侵网站服务器的常见手法有哪些?
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
如何快速上传建站程序避免常见错误?
JavaScript如何实现路由_前端路由原理是什么
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
如何在万网利用已有域名快速建站?
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
高防服务器租用首荐平台,企业级优惠套餐快速部署
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
如何挑选优质建站一级代理提升网站排名?
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
怎样使用JSON进行数据交换_它有什么限制
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】

