C++遍历std::string拆分int与char存入vector的最高效实现方法
实现方案
核心思路
- 最优时间复杂度为O(n)(n为输入字符串长度),仅需一次遍历即可完成拆分,这是理论最低时间复杂度:必须访问字符串的每一个字符才能判断类型完成拆分,没有优化空间
- 遍历过程中维护临时变量累计连续数字的值,遇到非数字字符时先完成累计数字的存储(如果有),再存储非数字字符
- 遍历结束后额外判断一次是否有未存储的末尾连续数字,处理边界场景
实现代码
#include <vector> #include <string> #include <cctype> void splitString(const std::string& input, std::vector<int>& numbers, std::vector<char>& notNumbers) { // 清空输出容器避免旧数据干扰 numbers.clear(); notNumbers.clear(); int currentNum = 0; bool hasNum = false; // 标记是否处于连续数字累计状态,避免0被误判为无效数字 for (unsigned char c : input) { // 转unsigned char避免isdigit触发未定义行为 if (std::isdigit(c)) { currentNum = currentNum * 10 + (c - '0'); hasNum = true; } else { // 先存储之前累计的连续数字 if (hasNum) { numbers.push_back(currentNum); currentNum = 0; hasNum = false; } // 存储非数字字符 notNumbers.push_back(static_cast<char>(c)); } } // 处理字符串末尾是连续数字的边界情况 if (hasNum) { numbers.push_back(currentNum); } } // 调用示例 int main() { std::string input = "82aw55beA1/de50Ie109+500s"; std::vector<int> numbers; std::vector<char> notNumbers; splitString(input, numbers, notNumbers); return 0; }
注意事项
- 使用
hasNum标记而非判断currentNum != 0,可以兼容输入中存在连续数字0的场景 - 传入
isdigit的字符强转为unsigned char,避免字符集为signed char时,负值字符触发未定义行为 - 如果输入的连续数字超出
int取值范围,可将currentNum和numbers的类型替换为long/long long适配
内容的提问来源于stack exchange,提问作者IndiaCharlie
相关产品推荐
相关产品推荐

