C++ stringstream 实战:5个LeetCode算法题高效输入解析与类型转换

C++ stringstream 实战:5个LeetCode算法题高效输入解析与类型转换
C stringstream 实战5个LeetCode算法题高效输入解析与类型转换在算法竞赛和技术面试中输入解析往往是解题的第一步也是最容易被忽视的环节。许多C程序员习惯使用传统的cin和getline但当面对复杂输入格式时这些方法往往显得力不从心。本文将深入探讨stringstream这一强大工具通过5个LeetCode典型题目展示如何利用它高效处理各种棘手的输入场景。1. stringstream核心机制解析stringstream是C标准库sstream中提供的字符串流类它将字符串与流操作完美结合。与文件流(fstream)类似但操作对象是内存中的字符串而非物理文件。关键特性对比特性stringstream优势传统方法局限类型安全自动类型推导避免格式错误scanf需手动匹配格式内存管理自动扩容无缓冲区溢出风险字符数组需预分配固定大小操作灵活性支持流式连续操作多次调用解析函数增加复杂度错误处理内置状态检测机制需额外检查返回值或异常处理基础用法示例#include sstream #include string // 字符串分割基础实现 void splitString(const std::string input) { std::stringstream ss(input); std::string token; while (ss token) { // 默认按空格分割 std::cout token std::endl; } }2. LeetCode典型输入处理场景2.1 不定长数字列表解析LeetCode 297. 二叉树的序列化二叉树序列化格式示例[1,2,3,null,null,4,5]。这种混合了符号和数字的输入需要特殊处理。高效解析方案vectorstring deserialize(string data) { vectorstring tokens; stringstream ss(data.substr(1, data.size()-2)); // 去除方括号 string item; while (getline(ss, item, ,)) { // 按逗号分割 tokens.push_back(item); } return tokens; }性能优化点使用substr避免临时字符串拷贝流对象复用减少构造开销预分配vector空间避免多次扩容2.2 混合类型数据行处理LeetCode 68. 文本左右对齐输入可能包含字符串和数字混合的情况如[This, is, an, example, 2]类型安全解析void processLine(const string line) { stringstream ss(line); string word; int num; while (ss word) { if (stringstream(word) num) { // 尝试转换为数字 handleNumber(num); } else { handleWord(word); } } }2.3 多分隔符复杂字符串LeetCode 819. 最常见的单词输入示例Bob hit a ball, the hit BALL flew far after it was hit.需要处理多种标点符号。正则表达式替代方案string mostCommonWord(string paragraph, vectorstring banned) { for (auto c : paragraph) { c isalpha(c) ? tolower(c) : ; // 非字母转为空格 } stringstream ss(paragraph); string word; unordered_mapstring, int freq; while (ss word) { if (find(banned.begin(), banned.end(), word) banned.end()) { freq[word]; } } return max_element(freq.begin(), freq.end())-first; }3. 高级应用技巧3.1 流状态控制与错误处理stringstream提供了完善的状态检测机制stringstream ss(123 abc 45.6); int x; double y; string z; ss x; // 成功读取123 if (ss.fail()) { ss.clear(); // 清除错误状态 } ss z; // 读取abc ss y; // 成功读取45.6 cout Read values: x , z , y endl;状态标志说明good()操作成功eof()到达流末尾fail()逻辑错误如类型不匹配bad()流损坏如内存不足3.2 高效类型转换模板封装可复用的类型转换工具templatetypename T T convertTo(const string str) { stringstream ss(str); T value; if (!(ss value)) { throw runtime_error(Conversion failed); } return value; } // 使用示例 int num convertToint(42); double pi convertTodouble(3.14159);4. 性能优化实践4.1 对象复用与内存管理频繁创建stringstream对象会导致性能下降正确的做法是class Parser { stringstream ss; public: templatetypename T T parse(const string input) { ss.str(input); // 重用现有流对象 ss.clear(); // 清除状态标志 T result; ss result; return result; } };4.2 与标准算法结合配合STL算法实现高效处理vectorint parseNumbers(const string line) { vectorint numbers; stringstream ss(line); // 使用istream_iterator简化输入 copy(istream_iteratorint(ss), istream_iteratorint(), back_inserter(numbers)); return numbers; }5. 完整解决方案与模板5.1 通用输入解析模板class InputParser { stringstream ss; public: explicit InputParser(const string input) : ss(input) {} // 解析定长数组 templatetypename T vectorT parseArray(char delim ,) { vectorT result; string item; while (getline(ss, item, delim)) { stringstream item_ss(item); T value; if (item_ss value) { result.push_back(value); } } return result; } // 解析键值对 templatetypename K, typename V pairK, V parsePair(char pair_delim :, char item_delim ,) { string pair_str; getline(ss, pair_str, item_delim); stringstream pair_ss(pair_str); K key; V value; getline(pair_ss, pair_str, pair_delim); stringstream(pair_str) key; pair_ss value; return {key, value}; } };5.2 LeetCode 151实战翻转字符串中的单词string reverseWords(string s) { stringstream ss(s); string word, result; while (ss word) { result word result; } if (!result.empty()) { result.pop_back(); // 移除末尾空格 } return result; }在处理算法题目时stringstream的价值不仅体现在输入解析阶段。它的类型转换能力可以大幅简化代码例如将数值转换为字符串进行比较或拼接string numToStr(int num) { stringstream ss; ss num; return ss.str(); }相比传统的to_string()这种方法在需要格式化输出时更为灵活string formatTime(int hours, int minutes) { stringstream ss; ss setw(2) setfill(0) hours : setw(2) setfill(0) minutes; return ss.str(); }