c++中如何实现字符串的按单词反转_c++双指针法反转逻辑【详解】
技术百科
尼克
发布时间:2026-01-22
浏览: 次 必须用双指针而非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
# int
# 指针
# 字符串
# 为什么
# const
# 切分
# 不含
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何在 Pandas 中按元素交集合并两列字符串
- c# await 一个已经完成的Task会发生什么
- Win11怎样安装钉钉客户端_Win11安装钉钉教
- Python实现图数据库操作_Neo4j核心CRU
- Win10如何更改网络连接_Windows10以太
- 如何在 Go 中比较自定义的数组类型(如 [20]
- Win11怎么开启专注模式_Windows11时钟
- php做exe支持多线程吗_并发处理实现方式【详解
- Win11怎么退出高对比度模式_Win11取消反色
- PHP怎么接收URL中的锚点参数_获取#后面参数值
- Python脚本参数接收_sys与argparse
- Python日志系统设计与实现_高可观测性架构实战
- 如何快速验证Golang安装是否成功_运行go v
- 如何正确访问 Laravel 模型或对象的属性而非
- 如何使用Golang理解结构体指针方法接收者_Go
- 如何更改Windows资源管理器的默认启动位置?(
- Windows 11无法安全删除U盘提示设备正在使
- c++中如何使用std::variant_c++1
- php删除数据怎么加限制_带where条件删除避免
- Python音视频处理高级项目教程_FFmpegP
- 如何在 ACF 中正确更新嵌套多层 Group 字
- C++中的Pimpl idiom是什么,有什么好处
- Win11怎么设置DNS服务器_Windows11
- Win11如何设置省电模式 Win11开启电池节电
- Mac版Final Cut Pro入门_Mac视频
- Python抽象类与接口设计_规范说明【指导】
- Win11怎么关闭通知中心_Windows11系统
- Mac怎么安装软件_Mac安装dmg与pkg文件的
- Win11键盘快捷键大全_Windows 11常用
- php嵌入式需要什么环境_搭建php+linux嵌
- c# F# 的 MailboxProcessor
- 如何在Windows中创建新的用户账户?(标准与管
- 如何在 Go 中高效缓存与分发网络视频流
- Python 中将 ISO 8601 时间戳转换为
- 使用类变量定义字符串常量时的类型安全最佳实践
- Windows10如何更改桌面背景_Win10个性
- Go语言中slice追加操作的底层共享机制详解
- Win10怎么关闭自动更新错误重启 Win10策略
- c++怎么设置线程优先级与cpu亲和性_c++ 多
- 为什么本地php环境运行php脚本卡顿_php执行
- Win11怎么开启移动热点_Windows11共享
- Win10怎样清理C盘爱奇艺缓存_Win10清理爱
- c++获取当前时间戳_c++ time函数使用详解
- 如何使用Golang编写单元测试_创建Test函数
- 静态属性修改会影响所有实例吗_php作用域操作符下
- c++中如何使用auto关键字_c++11类型推导
- 电脑的“网络和共享中心”去哪了_Windows 1
- Win11怎么关闭通知消息_屏蔽Windows 1
- Mac如何与安卓手机传文件_Mac和Android
- Win11怎么开启远程桌面_Win11系统远程桌面

QQ客服