单循环实现字符串删除替换遇问题,求STL算法解决方案
字符串连字符转驼峰:错误修复与STL算法实现
问题说明
输入字符串 "the-new-year",目标是转换为驼峰格式 "theNewYear",但提供的单循环实现代码输出错误结果 "theNnewYyear",需用STL算法优化实现。
原错误代码
std::string convert(std::string text) { std::string val; auto index{ 0 }; for (auto x : text) { if (x != '-') { val.push_back(x); index++; } else { val.push_back(std::toupper(text[index+1])); index++; } } return val; }
错误根源
原代码混用范围for循环和手动维护的index变量:
- 遇到
'-'时,代码直接将text[index+1]转大写加入结果,但后续范围for循环仍会遍历到该位置的字符,再次将其加入结果,导致重复字符(比如-n会被处理成N,之后循环到n又添加一次,变成Nn)。 index的递增逻辑与范围for的遍历不同步,进一步造成位置跟踪混乱。
STL算法解决方案
以下是两种基于STL标准算法的实现方式,逻辑清晰且避免手动索引错误:
方案1:std::remove_if + std::transform 组合
先移除所有连字符,再将原连字符后的字符转为大写:
#include <algorithm> #include <cctype> #include <string> std::string convert(std::string text) { bool capitalize_next = false; // 移除所有'-',同时标记需要转大写的位置 auto new_end = std::remove_if(text.begin(), text.end(), [&capitalize_next](char c) { if (c == '-') { capitalize_next = true; return true; } return false; }); // 遍历字符串,将标记位置的字符转大写 std::transform(text.begin(), new_end, text.begin(), [&capitalize_next](char c) { if (capitalize_next) { capitalize_next = false; return std::toupper(static_cast<unsigned char>(c)); } return c; }); // 截断移除后的冗余部分 text.erase(new_end, text.end()); return text; }
方案2:std::accumulate 逐步构建结果
利用std::accumulate迭代构建目标字符串,同时跟踪是否需要将下一个字符转大写:
#include <numeric> #include <cctype> #include <string> std::string convert(const std::string& text) { return std::accumulate(text.begin(), text.end(), std::string{}, [](std::string& result, char c) { static bool capitalize = false; if (c == '-') { capitalize = true; } else { if (capitalize) { result.push_back(std::toupper(static_cast<unsigned char>(c))); capitalize = false; } else { result.push_back(c); } } return result; }); }
方案优势
- 依托STL算法的封装性,规避手动循环的索引错误风险。
- STL算法经过优化,性能优于简单手动实现。
- 逻辑拆分清晰,代码可读性和可维护性更强。
内容的提问来源于stack exchange,提问作者Hariom Singh
相关产品推荐
相关产品推荐

