不能直接用 std::reverse 整个字符串,因为会整体翻转导致单词内部字符顺序也颠倒,违背“保持单词顺序、仅反转单词内字符”的要求;应逐词拆分并反转,如用 std::istringstream 提取单词后对每个调用 std::reverse。

为什么不能直接用 std::reverse 整个字符串?
直接对整个字符串调用 std::reverse 会把字符顺序全翻过来,比如 "hello world" 变成 "dlrow olleh",单词内部也反了——这不符合“Keep Word Order”要求。目标是保持单词位置不变,只反转每个单词内部的字符。
用 std::istringstream 拆词 + std::reverse 逐词处理
这是最直观、不易出错的做法:按空格切分单词,单独反转每个单词,再拼回去。注意保留原始空格结构(如多个连续空格)需要更谨慎,但多数场景只要求“单词内反转、空格归一化”即可。
实操建议:
- 用
std::istringstream自动跳过多余空格,读出干净单词 - 每个单词存入
std::vector<:string></:string>,用std::reverse处理其begin()/end() - 拼接时手动加单空格,避免末尾多余空格
- 若需保留原空格布局(如制表符、连续空格),改用双指针扫描更稳妥
std::string s = " hello world ";
std::istringstream iss(s);
std::vector<:string> words;
std::string word;
while (iss >> word) {
std::reverse(word.begin(), word.end());
words.push_back(word);
}
std::string result;
for (size_t i = 0; i 0) result += " ";
result += words[i];
}
// result == "olleh dlrow"
</:string>
双指针原地反转(不依赖额外容器,适合大字符串)
如果内存敏感或字符串极大,避免 std::vector 和多次字符串拼接,可用双指针在原字符串上操作。关键点是识别单词边界:非空格连续段为一个单词。
常见错误现象:
- 忽略开头/结尾空格,导致越界访问
s[i] - 内层循环结束条件写成
i 而不是 <code>i ,多交换一次 - 外层循环跳过空格后没检查
i ,触发未定义行为
实操要点:
- 外层用
i扫描,遇到非空格就记下起点start = i - 内层用
j向右扩展直到空格或结尾,然后对[start, j)区间调用std::reverse或手写交换 - 每次内层结束后,
i直接设为j + 1,跳过刚处理完的单词和后续空格
遇到 Unicode(如中文、emoji)怎么办?
std::string 是字节序列,直接按 char 反转会破坏 UTF-8 编码。例如中文“你好”在 UTF-8 中占 6 字节,按字节反转后变成非法序列。
此时必须先做 Unicode 字符拆分:
- C++20 起可尝试
std::u8string+std::ranges::views::utf8(支持度有限) - 更稳妥是用 ICU 库或第三方 UTF-8 解码函数,把字符串转成
std::vector<char32_t></char32_t>,再按 code point 反转 - 简单项目若确定只处理 ASCII,可忽略此问题;但一旦输入含非 ASCII 字符,就必须显式处理编码
容易被忽略的地方是:本地测试用英文没问题,上线后用户输入带 emoji 的昵称,程序突然崩溃或输出乱码——这不是算法错,是字符编码假设错了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











