#19249. 书童的虚词账本
书童的虚词账本
文言文(Classical Chinese)以言简意赅著称,其中虚词(如“之、乎、者、也”)虽然没有实在的意义,却是构成文章语气和节奏的灵魂。
苏轼在《日喻》中说:“之乎者也,助得甚事?” 但对于信息学来说,统计这些字出现的频率,是考察 哈希表(HashMap) 最经典的场景:我们需要建立一个从“汉字(String)”到“出现次数(Int)”的映射关系。
我为你构思了这道题目,背景设定为一位古代书童整理经书的过程。
[OI 题库] 书童的“虚词账本” (The Scholar's Particle Counter)
题目背景
“学而时习之,不亦说乎?” —— 《论语》
古代的私塾里,老夫子正在讲授经书。书童“小乙”的任务是整理夫子的手稿。夫子最近对文章的韵律非常痴迷,他想知道在这一卷经文中,那些常用的虚词(如“之”、“乎”、“者”、“也”、“矣”、“焉”、“哉”)分别出现了多少次。
经文由一个个汉字组成。由于汉字数量众多,小乙不可能在脑子里记住每一个字的位置。他需要一个神奇的“账本”,每读到一个字,就在账本上对应的名字后面画一道杠(计数)。
题目描述
给定一篇包含 个汉字(或词语)的文言文文章。 再给定 次查询,每次查询给出一个特定的汉字。
请你利用“哈希表”技术,快速回答每一个被查询的汉字在文章中一共出现了多少次。
注意:
- 输入不考虑标点符号,所有汉字以空格或换行分隔。
- 如果没有出现过该字,请输出 0。
输入格式
第一行一个整数 ,表示文章中汉字的总数。 第二行包含 个字符串,表示文章内容(每个字符串代表一个汉字或词)。 第三行一个整数 ,表示查询的次数。 接下来 行,每行一个字符串,表示要查询的汉字。
输出格式
共 行。每行一个整数,表示该汉字在文章中出现的频率。
样例数据
样例 1
10
学 而 时 习 之 不 亦 说 乎 之
3
之
乎
者
2
1
0
样例解析:
- 文章内容:“学 而 时 习 之 不 亦 说 乎 之”
- 查询“之”:出现了 2 次。
- 查询“乎”:出现了 1 次。
- 查询“者”:文章中未出现,输出 0。
数据范围
- 输入的汉字(字符串)长度不超过 3 字节(UTF-8编码下的单个汉字)或 10 字节(词组)。
- 考察点:
std::unordered_map或std::map的基本使用(插入、查找、计数)。
阿西莫夫的解题指南
这道题将语文的 “字义分析” 抽象为了计算机的 “键值对映射(Key-Value Mapping)”。
- 数据结构选择:
- 如果我们用两个数组,一个存字,一个存次数,每次查询都要遍历整个数组,复杂度是 ,这太慢了。
- 我们需要一个 或 查询速度的容器。
std::map<string, int>(基于红黑树,有序)或std::unordered_map<string, int>(基于哈希表,无序)是最佳选择。
- 核心逻辑:
- 预处理(建表):遍历文章,每读到一个词
s,就执行counts[s]++。这行代码的含义是:如果在表中找不到s,则新建并初始化为0再加1;如果找到了,直接加1。 - 查询:直接输出
counts[query_word]。如果表中不存在该键,STL 的 map 会自动返回 0(默认构造值),非常方便。
- 预处理(建表):遍历文章,每读到一个词