当前位置:首页 > GESP > 2023年GESP四级小杨的字典(洛谷B3927)解题报告:基于哈希表的字符串替换优化

2023年GESP四级小杨的字典(洛谷B3927)解题报告:基于哈希表的字符串替换优化

1天前

2023年GESP四级小杨的字典(洛谷B3927)解题报告:基于哈希表的字符串替换优化 GESP四级 洛谷B3927 哈希表优化 字符串替换算法 标点符号处理 第1张

一、题目解读

题目要求实现一个“字典替换”功能:给定一个字典(键值对映射)和一段文本,将文本中出现的字典中的单词替换为其对应的值,未匹配的单词用“UNK”代替。需处理标点符号分隔单词,并确保输入异常情况的容错性。问题核心在于高效查找替换与字符边界处理。

二、解题思路

1. 哈希表优化:使用unordered_map存储字典,实现O(1)平均时间复杂度的查找,避免线性扫描

2. 标点符号处理:自定义isPunctuation函数通过预定义字符串常量快速判断标点,减少字符遍历开销。

3. 流优化:通过ios::sync_with_stdio(false)和cin.tie(nullptr)禁用同步,提升输入效率。

4. 边界处理:利用current变量累积单词,遇到标点或末尾时触发替换,确保完整处理所有单词。

三、解题步骤

1. 初始化:读取字典数量N,创建unordered_map,循环处理键值对存入字典。

2. 输入清理:使用cin.ignore()清除换行符,确保getline正确读取后续文本。

3. 单词分段:遍历文本字符,若为标点则分割当前单词并替换(存在则替换,不存在则"UNK"),标点直接输出;若为字母则累积至current。

4. 末尾处理:文本末尾可能存在未处理的单词,需额外检查并替换。

5. 输出结果:拼接处理后的字符串并输出。

四、代码和注释

#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; // 结果串和当前累积单词
    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"; // 替换或"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;
}

五、总结

该解法通过哈希表实现了高效的单词查找替换,结合标点符号预处理和输入流优化,在时间和空间复杂度上均表现优异。代码逻辑清晰,边界处理严谨,对输入异常情况(如空键过滤)进行了合理容错。此外,静态常量字符串的标点判断避免了重复构建,进一步提升了性能。适用于处理大规模字典与文本的替换场景。


原创内容 转载请注明出处

分享给朋友:

相关文章

2024年GESP四级宝箱题(洛谷P4006)题解:滑动窗口算法优化最长子序列和

2024年GESP四级宝箱题(洛谷P4006)题解:滑动窗口算法优化最长子序列和

一、题目解读本题为2024年GESP四级中的“宝箱”问题(对应洛谷P4006),要求在一个由n个宝箱组成的序列中,找出一个连续子序列,使得该子序列中宝箱价值之和最大,且子序列中最大值与最小值的差不超过...

2023年GESP四级田忌赛马算法解析(洛谷B3928)— C++双指针策略与代码详解

2023年GESP四级田忌赛马算法解析(洛谷B3928)— C++双指针策略与代码详解

一、题目解读“田忌赛马”源自中国古代典故,田忌通过策略性安排马匹对阵顺序,以弱马对阵强马、强马对阵弱马的方式,实现整体胜利。在算法竞赛中,该问题通常转化为:给定两方马匹的战斗力数组,如何通过对阵策略最...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。