C++二叉树输入流处理需求:忽略数字、符号作分隔符
二叉树单词流处理:正确的字符分隔与过滤实现
初始实现及问题
最初的input方法尝试读取输入流中的字符串,处理后加入二叉树,但存在两个明显问题:
void WordTree::input(std::istream& in) { std::string str; while (in >> str) { // 转换为小写 std::transform(str.begin(), str.end(), str.begin(), ::tolower); // 删除数字和标点 str.erase(std::remove_if(str.begin(), str.end(), ::isdigit), str.end()); str.erase(std::remove_if(str.begin(), str.end(), ::ispunct), str.end()); // 添加到树中 if (str != " ") add(str); } }
测试结果问题
测试输入:
std::string str_input = " 100 2/3 alakazam qwerty up-time level up up up up bastion how are you 23 ALAKAZAM"
输出暴露两个问题:
- 出现空单词计数(显示
occurrences: 3):非空判断逻辑错误,应该检查字符串是否为空!str.empty(),而非判断是否等于空格字符串" "。 "up-time"被合并为"uptime":原实现先把up-time当作一个完整token读取,再删除标点,不符合“将符号作为分隔符拆分单词”的需求。
错误的逐字符尝试
改用逐字符读取的实现后,所有单词被拼接成长串,完全不符合预期:
void WordTree::input(std::istream& in) { char c; std::string str; while (in >> c) { if (std::isalpha(c)) { str = str + c; } else if (str != "") { std::transform(str.begin(), str.end(), str.begin(), ::tolower); add(str); str = ""; } } }
问题根源:while (in >> c)会自动跳过所有空白字符,导致空格无法触发单词分隔,所有字母被连续拼接。
正确的实现方案
采用逐字符读取所有字符(包括空白)的方式,将所有非字母字符(数字、标点、空格)视为单词分隔符,逻辑如下:
- 遍历每个字符,仅保留字母字符,直接转换为小写并加入当前单词。
- 遇到非字母字符时,若当前单词非空,则将其加入二叉树并清空。
- 循环结束后,处理最后一个未完成的单词。
void WordTree::input(std::istream& in) { char c; std::string current_word; // 读取所有字符,包括空白、标点、数字 while (in.get(c)) { // 转换为unsigned char避免std::isalpha的未定义行为 unsigned char uc = static_cast<unsigned char>(c); if (std::isalpha(uc)) { // 直接转小写并加入当前单词 current_word += static_cast<char>(std::tolower(uc)); } else { // 非字母字符触发单词结束 if (!current_word.empty()) { add(current_word); current_word.clear(); } // 非字母字符直接忽略 } } // 处理循环结束后剩余的单词 if (!current_word.empty()) { add(current_word); } }
实现说明
in.get(c):读取输入流中的每一个字符,包括空白、标点和数字,不会自动跳过,确保所有分隔符都能被捕获。std::isalpha的安全调用:将char转换为unsigned char,避免处理负数值字符时的未定义行为。- 实时转小写:遇到字母时直接转换为小写,无需事后对整个字符串调用
std::transform,提升效率。 - 收尾处理:循环结束后检查剩余单词,避免遗漏最后一个未被分隔符终止的单词。
测试验证
使用原测试输入,处理后将得到正确结果:
alakazam:2次qwerty:1次up:5次(up-time拆分出的up+ 后续4个up)time:1次level:1次bastion:1次how:1次are:1次you:1次
无空单词计数,完全符合需求。
内容的提问来源于stack exchange,提问作者Hofbr
相关产品推荐
相关产品推荐

