#19250. 书籍编纂

书籍编纂

你好,我是阿西莫夫。

在上一题中,我们用“哈希表”解决了快速查找的问题,那就像是一个杂乱无章但取用方便的杂物箱。

但是,古人治学讲究 “条理”“次序”。 编纂《康熙字典》或《广韵》时,编纂者绝不能把字随便乱堆,必须按照部首、笔画或音韵严格排序。这种**“不仅要存,还要有序”**的需求,正是 std::map(有序映射) 的用武之地。

std::map 的底层通常是红黑树。当你把数据扔进去时,它不仅保存了数据,还顺手把它们按字典序排好了队。

为了考察这一特性,我为你构思了这道关于 “整理韵书” 的题目。


[OI 题库] 翰林院的《韵书》编纂 (Compiling the Book of Rhymes)

题目背景

“礼乐征伐自天子出,书同文,车同轨。” —— 历史的秩序

翰林院正在编修一部新的《大典》。为了统一全国的读音,老学究们收集了民间大量的诗歌和文章。现在,他们需要制作一张 “字频表”

这张表有两个严格的要求:

  1. 统计:算出每一个拼音(代表一个音韵)在文献中出现了多少次。
  2. 排序:为了方便查阅,输出时必须按照拼音的字典序(A-Z)从前到后排列。

如果让你手动排序,恐怕要累死在书堆里。但在 C++ 中,只需要换一种容器,这一切都是自动完成的。

题目描述

给定包含 NN 个字符串的文本(每个字符串代表一个汉字的拼音)。 请统计每个拼音出现的次数,并按照字典序(ASCII 码顺序)从小到大输出所有出现过的拼音及其次数。

输入格式

第一行一个整数 NN,表示文献中拼音的总数。 接下来 NN 行,每行一个字符串 SS,表示一个拼音。

输出格式

输出若干行。 每一行包含一个字符串和一个整数,中间用空格分隔,表示拼音及其出现次数。 要求:必须严格按照拼音字符串的字典序输出。

样例数据

样例 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。
  • 排序输出
    1. hu (h 开头,排第一) -> 2次
    2. yan (y 开头,ya 比 ye 靠前) -> 1次
    3. ye -> 1次
    4. yi -> 1次
    5. zhe (z 开头,zh 相同比 e/i) -> 1次
    6. zhi -> 2次

数据范围

  • 1N100,0001 \le N \le 100,000
  • 字符串长度 10\le 10,仅包含小写英文字母。

阿西莫夫的解题指南

这道题与上一道“虚词账本”唯一的区别在于:输出要求有序

  1. 容器选择
    • 如果用 unordered_map,统计完之后,你得到的是一堆乱序的数据。想排序?你得把它们全部倒进一个 vector,再调用 std::sort,非常麻烦。
    • 如果用 std::map,它在插入的那一刻就已经把位置排好了(红黑树插入)。
  2. 遍历输出
    • 直接使用迭代器(Iterator)或 C++11 的 range-based for 循环遍历 map,它会自动按照 Key(拼音)从小到大的顺序吐出数据。这是 std::map 最迷人的特性。