不能直接用 std::reverse,因为它会将整个字符串倒序(如 "hello world" → "dlrow olleh"),而目标是单词顺序反转、单词内字符不变;需先整体翻转,再逐个单词翻转,配合双指针识别单词边界并处理空格。

为什么不能直接用 std::reverse 对整个字符串?
因为 std::reverse 会把整个字符串倒过来,比如 "hello world" 变成 "dlrow olleh",而不是想要的 "world hello"。真正要的是「单词顺序反转,单词内字符不变」——这是两层翻转:先整体翻,再逐个单词翻回来。
标准做法:两次 std::reverse + 手动找单词边界
核心思路是:先翻整个字符串,再遍历识别空格分隔的子串,对每个子串单独翻转。C++ 没有内置“按空格切分并原地反转”的函数,所以得自己扫一遍。
- 用
std::reverse(str.begin(), str.end())先全局翻转 - 用两个指针
start和i遍历,遇到空格或结尾时,对[start, i)区间调用std::reverse - 注意处理连续空格:跳过它们,避免生成空单词或越界
- 如果字符串以空格结尾,
i == str.length()时也要触发最后一次反转
示例片段:
void reverseWords(std::string& s) {
std::reverse(s.begin(), s.end());
size_t start = 0;
for (size_t i = 0; i <= s.length(); ++i) {
if (i == s.length() || s[i] == ' ') {
if (i > start) {
std::reverse(s.begin() + start, s.begin() + i);
}
start = i + 1;
}
}
}
遇到前后/中间多余空格怎么办?
上面的逻辑保留原空格布局。如果需求是「去掉多余空格、只留单空格分隔」(常见于算法题),就不能只靠翻转,得先清洗再翻转。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 推荐用
std::stringstream提取非空单词,但会额外分配内存,不满足“原地”要求 - 真要原地去空格:双指针法,一个读一个写,跳过连续空格,手动压缩;完成后截断尾部,再执行两次翻转
- 注意:
s.erase()或s.resize()会影响后续索引,必须在清洗完再做翻转
性能关键点:别用 substr + + 拼接
有人想先 split 再 reverse vector 再 join,这在 C++ 里非常慢:substr 频繁分配,+ 字符串拼接可能触发多次内存重分配。
-
std::string的append或reserve配合移动语义能缓解,但不如原地翻转 O(1) 空间 - 如果输入长度上万,原地两次
std::reverse是最优解,时间 O(n),空间 O(1) - 编译器对
std::reverse通常做了优化,内部是 memmove 或循环交换,比手写 for 更稳
边界情况容易漏:空字符串、全空格、单单词、开头结尾空格——每种都得在循环里用 i == s.length() 和 i > start 卡住。

















