刷题要存两个数的映射,业务里要做 id 到对象的索引,c++哈希表不用自己手写,标准库的 unordered_map 就是哈希表实现,平均查找 O(1),一行 include 就能用。数组模拟哈希是竞赛玩法,业务代码没必要。

基本操作

#include <unordered_map>   std::unordered_map<int, std::string> m;   m[1001] = "张三";   if (m.count(1001)) { }   m.erase(1001);

方括号访问有个副作用:key 不存在时会自动插入默认值,只想查询就用 find,拿返回的迭代器跟 end 比较,不然容器越查越大,内存悄悄涨。value 是自定义类时,方括号插入要调默认构造,类没有默认构造就编译不过,这种情况一律用 insert 或 emplace,插入对象还能省一次拷贝。

和 map 怎么选

unordered_map 查得快,但遍历顺序不确定;map 是红黑树,key 有序,遍历天然按序输出,代价是 O(log n)。要对 key 排序输出就用 map,只做查找映射就 unordered_map,多数场景后者够用。多线程并发读写要自己加锁,标准容器不做线程安全,这点别指望。key 是字符串时直接用默认配置就行,别重复造轮子。

自定义类型做 key

拿自己的结构体当 key,要给 unordered_map 提供哈希函数和相等比较,通常手写一个 hash 仿函数传进模板参数,再重载相等比较。嫌麻烦就换个思路,把几个字段拼成字符串或整数再当 key,先跑起来再优化。哈希函数要分布均匀,把所有字段直接相加的写法容易碰撞扎堆。

元素个数能预估就用 reserve 预留,避免反复扩容抖动;遍历时删除元素,erase 会返回下一个迭代器,接着用它继续走,别拿失效的迭代器访问。业务代码里 c++哈希表 的需求,unordered_map 基本都能接住。