C++新手求助:双分隔符处理stringstream的资源优化实现
双分隔符字符串分割的高效实现方案
作为一名C++新手,要实现先按第一个分隔符、再按第二个分隔符分割字符串,同时兼顾资源效率,咱们可以从减少内存分配和避免冗余遍历这两点入手。下面我给你一个优化后的实现思路和代码:
核心优化思路
- 优先使用无拷贝的字符串引用(C++17的
std::string_view),避免不必要的内存开销 - 每一级分割只遍历对应范围的字符,没有冗余循环,总遍历次数是理论最小值
- 利用移动语义减少容器元素的拷贝操作
高效实现代码(C++17及以上)
#include <vector> #include <string> #include <string_view> std::vector<std::vector<std::string_view>> dualDelimit(const std::string& input, char first_delim, char second_delim) { std::vector<std::vector<std::string_view>> result; size_t start = 0; // 第一级分割:按第一个分隔符拆分原字符串 for (size_t i = 0; i <= input.size(); ++i) { if (i == input.size() || input[i] == first_delim) { std::string_view first_sub(input.data() + start, i - start); if (!first_sub.empty()) { // 可根据需求决定是否保留空串 std::vector<std::string_view> second_level; size_t sub_start = 0; // 第二级分割:按第二个分隔符拆分当前第一级子串 for (size_t j = 0; j <= first_sub.size(); ++j) { if (j == first_sub.size() || first_sub[j] == second_delim) { std::string_view second_sub = first_sub.substr(sub_start, j - sub_start); if (!second_sub.empty()) { second_level.push_back(second_sub); } sub_start = j + 1; } } result.push_back(std::move(second_level)); // 移动语义避免容器拷贝 } start = i + 1; } } return result; } // 测试用例 #include <iostream> int main() { std::string test_input = "a,b;c,d;e,f"; auto split_result = dualDelimit(test_input, ';', ','); // 打印结果 for (const auto& level1 : split_result) { for (const auto& level2 : level1) { std::cout << level2 << " "; } std::cout << "\n"; } return 0; }
兼容性版本(C++11/14)
如果你的编译器不支持C++17,把std::string_view换成std::string即可,逻辑完全一致,只是会增加少量字符串拷贝:
#include <vector> #include <string> std::vector<std::vector<std::string>> dualDelimit(const std::string& input, char first_delim, char second_delim) { std::vector<std::vector<std::string>> result; size_t start = 0; for (size_t i = 0; i <= input.size(); ++i) { if (i == input.size() || input[i] == first_delim) { std::string first_sub = input.substr(start, i - start); if (!first_sub.empty()) { std::vector<std::string> second_level; size_t sub_start = 0; for (size_t j = 0; j <= first_sub.size(); ++j) { if (j == first_sub.size() || first_sub[j] == second_delim) { std::string second_sub = first_sub.substr(sub_start, j - sub_start); if (!second_sub.empty()) { second_level.push_back(second_sub); } sub_start = j + 1; } } result.push_back(std::move(second_level)); } start = i + 1; } } return result; }
测试结果示例
用测试数据"a,b;c,d;e,f"运行代码,会输出:
a b
c d
e f
这个实现的循环次数是完全必要的——毕竟每个字符都需要被检查是否是分隔符,没有多余的重复遍历;同时通过string_view和移动语义把资源占用降到了最低。
内容的提问来源于stack exchange,提问作者Madryoch
相关产品推荐
相关产品推荐

