#19250. 书籍编纂
书籍编纂
你好,我是阿西莫夫。
在上一题中,我们用“哈希表”解决了快速查找的问题,那就像是一个杂乱无章但取用方便的杂物箱。
但是,古人治学讲究 “条理” 与 “次序”。
编纂《康熙字典》或《广韵》时,编纂者绝不能把字随便乱堆,必须按照部首、笔画或音韵严格排序。这种**“不仅要存,还要有序”**的需求,正是 std::map(有序映射) 的用武之地。
std::map 的底层通常是红黑树。当你把数据扔进去时,它不仅保存了数据,还顺手把它们按字典序排好了队。
为了考察这一特性,我为你构思了这道关于 “整理韵书” 的题目。
[OI 题库] 翰林院的《韵书》编纂 (Compiling the Book of Rhymes)
题目背景
“礼乐征伐自天子出,书同文,车同轨。” —— 历史的秩序
翰林院正在编修一部新的《大典》。为了统一全国的读音,老学究们收集了民间大量的诗歌和文章。现在,他们需要制作一张 “字频表”。
这张表有两个严格的要求:
- 统计:算出每一个拼音(代表一个音韵)在文献中出现了多少次。
- 排序:为了方便查阅,输出时必须按照拼音的字典序(A-Z)从前到后排列。
如果让你手动排序,恐怕要累死在书堆里。但在 C++ 中,只需要换一种容器,这一切都是自动完成的。
题目描述
给定包含 个字符串的文本(每个字符串代表一个汉字的拼音)。 请统计每个拼音出现的次数,并按照字典序(ASCII 码顺序)从小到大输出所有出现过的拼音及其次数。
输入格式
第一行一个整数 ,表示文献中拼音的总数。 接下来 行,每行一个字符串 ,表示一个拼音。
输出格式
输出若干行。 每一行包含一个字符串和一个整数,中间用空格分隔,表示拼音及其出现次数。 要求:必须严格按照拼音字符串的字典序输出。
样例数据
样例 1
8
zhi
hu
zhe
ye
zhi
hu
yi
yan
hu 2
yan 1
ye 1
yi 1
zhe 1
zhi 2
样例解析:
- 输入顺序是乱的:
zhi,hu,zhe... - 统计结果:
zhi=2,hu=2,zhe=1,ye=1,yi=1,yan=1。 - 排序输出:
hu(h 开头,排第一) -> 2次yan(y 开头,ya 比 ye 靠前) -> 1次ye-> 1次yi-> 1次zhe(z 开头,zh 相同比 e/i) -> 1次zhi-> 2次
数据范围
- 字符串长度 ,仅包含小写英文字母。
阿西莫夫的解题指南
这道题与上一道“虚词账本”唯一的区别在于:输出要求有序。
- 容器选择:
- 如果用
unordered_map,统计完之后,你得到的是一堆乱序的数据。想排序?你得把它们全部倒进一个vector,再调用std::sort,非常麻烦。 - 如果用
std::map,它在插入的那一刻就已经把位置排好了(红黑树插入)。
- 如果用
- 遍历输出:
- 直接使用迭代器(Iterator)或 C++11 的
range-based for循环遍历map,它会自动按照 Key(拼音)从小到大的顺序吐出数据。这是std::map最迷人的特性。
- 直接使用迭代器(Iterator)或 C++11 的