2023年GESP四级小杨的字典(洛谷B3927题):字典查找详解
一、问题分析与解题思路
本题目要求实现一个简单的字典查找系统,能够将输入句子中的单词替换为字典中对应的翻译,未找到的单词标记为"UNK"。核心算法包括:字典存储、字符串分割和查找替换。
二、完整代码解析(含详细注释)
#include <iostream> #include <string> #include <unordered_map> #include <cctype> using namespace std; // 优化后的标点符号判断函数 bool isPunctuation(char c) { static const string punct = "!()-.[].{}\\|;:'\",./?<>"; return punct.find(c) != string::npos; } int main() { ios::sync_with_stdio(false); // 提高输入输出效率 cin.tie(nullptr); // 解除cin和cout的绑定 int N; cin >> N; // 读取字典条目数 unordered_map<string, string> dict; // 使用哈希表存储字典 // 读取字典条目 for (int i = 0; i < N; ++i) { string a, b; cin >> a >> b; if (!a.empty()) dict[a] = b; // 避免空键 } cin.ignore(); // 清除缓冲区中的换行符 string s; getline(cin, s); // 读取待处理的整行文本 string result, current; // result存储最终结果,current暂存当前单词 for (size_t i = 0; i < s.size(); ++i) { char c = s[i]; if (isPunctuation(c)) { // 遇到标点符号 // 处理已积累的单词 if (!current.empty()) { auto it = dict.find(current); result += (it != dict.end()) ? it->second : "UNK"; current.clear(); } result += c; // 保留标点符号 } else { current += c; // 积累单词字符 } } // 处理末尾可能的剩余单词 if (!current.empty()) { auto it = dict.find(current); result += (it != dict.end()) ? it->second : "UNK"; } cout << result << endl; return 0; }
三、关键技术点解析
字典存储:使用unordered_map实现高效查找,时间复杂度接近O(1)
输入优化:ios::sync_with_stdio(false)和cin.tie(nullptr)提升IO效率
标点处理:单独定义isPunctuation函数判断标点符号
单词分割:通过逐个字符检查,遇到标点视为单词边界
异常处理:避免空键插入字典,正确处理末尾单词
四、常见问题解答
Q:为什么使用unordered_map而不是map? A:unordered_map基于哈希表实现,查找效率更高(O(1)),适合本题需求。
Q:cin.ignore()的作用是什么? A:清除输入缓冲区中的换行符,避免影响后续getline读取。
Q:如何处理连续的标点符号? A:代码会自动处理标点间的空单词,不会产生多余的"UNK"。
原创内容 转载请注明出处