为什么set_intersection算法仅在两文本字符串顺序完全一致时返回匹配结果
程序异常根因
- 嵌套文件读取逻辑错误:代码采用双层循环逐行读取两个词典文件,当外层第一次遍历正向词典(file1)时,内层循环会将反向词典(file2)从开头完整读到文件末尾。后续所有外层迭代中,file2的读取指针已停在文件结尾,无法再读出有效内容,直接导致文件词汇顺序不一致时无任何匹配输出。
- 词汇存储逻辑失效:代码在遍历单个分词token时才新建对应词典的存储vector,每次仅向vector中塞入当前遍历的单个单词,从未将整个词典的所有词汇完整存入容器。实际运行时每次仅对比两个单独取出的单词是否相等,自然只有词汇顺序完全一致时才能碰巧命中匹配。
- 文本清洗逻辑缺失:文件中的词汇前后常带有多余空格(如示例反向词典中
dog后紧跟的空格),分词得到的token会保留这些空白字符,导致同拼写词汇的字符串比对失败,无法完成匹配。 - 分词逻辑位置错误:代码将分词器初始化逻辑嵌套在单词遍历循环内部,每次处理单个单词时才重新拆分文本,完全没有实现“把整段文本拆分为独立词汇”的基础目标。
修复方案
- 重构文件读取流程:取消嵌套读文件的结构,先单独、完整读取正向词典文件,将所有经过清洗的有效词汇存入正向词典存储vector;再单独、完整读取反向词典文件,将所有有效词汇存入反向词典存储vector。
- 增加文本清洗步骤:对每个分词得到的token,移除首尾所有空白字符(空格、制表符、换行符),过滤掉空字符串类的无效token。
- 按照算法要求排序:对两个存储全量词汇的vector分别执行排序操作,满足
set_intersection算法的输入前置要求。 - 计算词汇交集:对两个排序后的vector执行交集计算,输出最终双向匹配的回文近亲词汇列表。
修复后参考代码
#include <iostream> #include <string> #include <fstream> #include <vector> #include <algorithm> #include <boost/tokenizer.hpp> #include <cctype> typedef boost::char_separator<char> separator_type; using namespace std; // 移除字符串首尾空白字符 string trim(const string& s) { auto start = s.begin(); while (start != s.end() && isspace(static_cast<unsigned char>(*start))) { start++; } auto end = s.end(); do { end--; } while (distance(start, end) > 0 && isspace(static_cast<unsigned char>(*end))); return string(start, end + 1); } // 从指定文件加载全量有效词汇 void load_dictionary(const string& filename, vector<string>& words_store) { ifstream file(filename); if (!file.is_open()) { cout << "无法打开文件: " << filename << endl; exit(1); } string line_content; const separator_type comma_sep(","); while (getline(file, line_content)) { boost::tokenizer<separator_type> tokens(line_content, comma_sep); for (auto& token : tokens) { string clean_word = trim(token); if (!clean_word.empty()) { words_store.push_back(clean_word); } } } file.close(); } int main() { vector<string> forward_dic, backward_dic; // 独立加载两个词典,避免嵌套读取的位置偏移问题 load_dictionary("Twoworddictionary.txt", forward_dic); load_dictionary("Backwardstwoworddictionary.txt", backward_dic); // 满足set_intersection的输入要求:两个输入序列均已排序 sort(forward_dic.begin(), forward_dic.end()); sort(backward_dic.begin(), backward_dic.end()); vector<string> match_result(forward_dic.size() + backward_dic.size()); auto result_end = set_intersection( forward_dic.begin(), forward_dic.end(), backward_dic.begin(), backward_dic.end(), match_result.begin() ); match_result.erase(result_end, match_result.end()); cout << "匹配的回文近亲词汇:" << endl; for (const auto& word : match_result) { cout << word << endl; } return 0; }
修复后程序可不受词典内词汇顺序影响:无论两个文件的词汇排列顺序是否一致,只要存在双向拼写匹配的有效词汇,即可正确输出结果。全量按字母序排列的大型词典场景下,也不会出现无匹配输出的问题。
内容的提问来源于stack exchange,提问作者maria9876
相关产品推荐
相关产品推荐

