10.哈希与字典树
哈希与字典树
哈希(Hash)也叫散列,记录存储位置与关键字之间存在对应关系 \(Loc(i)=H(key_{i})\),从而在查找数据时可以接近 \(O(1)\) 的效率直接找到位置,而不需要顺序摸排或二分查找。

哈希函数自由度很高,能完成数据范围到哈希表范围的映射就可以,映射之后有概率产生冲突,通过一定手段解决冲突即可。
工程应用中,MD4、SHA-1、SHA-256、SHA-512 等都是哈希算法。
链表法处理哈希冲突
哈希表每个位置对应一条链表,所有散列值相同的元素都放到相同位置对应的链表中

1 | list<int> hl[maxn]; |
STL 的 map 与
unorderd_map
C++ 的 STL 利用红黑树封装了 \(O(logn)\) 的 map
映射,以及一套哈希方案封装的接近\(O(1)\)的 unordered_map
映射,用起来很方便。
1 | std::unordered_map<string, int> mp; |
不同版本的C++
,unordered_map
内部实现不尽相同,一些题目可能会专门Hack
unordered_map
导致其退化不再是 \(O(1)\),所以比赛中如果理论复杂度用map
没问题的话,还是推荐用map
。
字典树
字典树是针对“串”类数据结构的哈希方案,比如对小写英文字符串做哈希,可以构建一个“26叉树”,将任意单词从左到右在树上进行分支查找,完成匹配。
1 | const int maxn = 1100; |
思考题
- 给n个单词,和1个长单词,求有多少个单词是这个长单词的前缀 —— 用 n 个单词建字典树,节点统计单词个数,长单词去匹配,路径上个数求和
- 给n个单词,和1个短单词,求这个短单词是多少个单词的前缀 —— 用 n 个单词建字典树,节点统计单词个数,短单词匹配成功的节点个数为答案
- 给两种语言单词对照表,输入任意单词,输出对照另一个语言的单词