如何修改C++代码实现文件中与输入单词仅差一字母的匹配输出
问题描述
程序需要接收用户输入的单词,打印输出文件中所有与输入单词仅相差一个字母的单词:
- 示例:输入为
"way"时,预期输出为[say, may, day, war, waw, wax, was...]
当前代码的问题是仅能查找出包含输入单词作为子串的词汇:
- 示例:输入
"start"时,实际输出为[restart, startup, started...]这类包含输入子串的结果,无法实现预期的单字母差异匹配效果。
原有实现代码如下:
#include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; void fileRead(vector<string>& v, ifstream& fin) { string line; while (getline(fin, line)) { v.push_back(line); } } void search(vector<string>& v, string word) { for (int i = 0; i < v.size(); i++) { int index = v[i].find(word); if (index != -1) cout << v[i] << endl; } } int main() { vector<string> wordVector; ifstream fin("text.txt"); if (!fin) { cout << "text.txt can't opened" << endl; return 0; } fileRead(wordVector, fin); fin.close(); cout << "reading text.txt." << endl; while (true) { cout << "Input a word: >>"; string word; getline(cin, word); if (word == "exit") break; search(wordVector, word); } cout << "Terminated" << endl; }
问题根因
原有search函数的匹配逻辑完全不符合需求:调用字符串find方法的作用是检测输入单词是否是当前词典单词的子串,和「仅相差一个字母」的匹配规则没有关联,因此会返回所有包含输入串的长单词,无法得到预期结果。
修改方法
对齐示例的单字母差异匹配(同长度单字符替换场景)判断逻辑分两步:
- 先判断词典单词长度是否和输入单词完全一致,长度不同直接跳过(长度差大于等于1时不可能满足同长度单字符替换的差异要求)
- 逐位对比两个单词的每个字符,统计不同字符的个数,若不同字符数恰好为1,则该单词符合要求,直接输出。对比过程中如果差异数已经超过1,可以提前终止当前单词的对比,减少不必要的计算。
直接替换原有代码中的search函数即可,修改后的实现如下:
void search(vector<string>& v, string word) { int inputLen = word.size(); for (int i = 0; i < v.size(); i++) { // 长度不一致直接跳过 if (v[i].size() != inputLen) { continue; } int diffCount = 0; for (int j = 0; j < inputLen; j++) { if (v[i][j] != word[j]) { diffCount++; // 差异超过1个,提前结束对比 if (diffCount > 1) { break; } } } // 恰好相差1个字符时输出 if (diffCount == 1) { cout << v[i] << endl; } } }
替换后重新编译运行,输入way即可得到预期的相邻单词列表,不会再返回包含输入子串的长单词。
如果需要支持「增删一个字母也算单字母差异」的场景(即单词长度和输入差1的情况也纳入匹配),只需要在长度判断分支补充对应编辑距离计算逻辑即可,当前实现完全匹配给出的示例效果。
内容的提问来源于stack exchange,提问作者서비로브자보키르
相关产品推荐
相关产品推荐

