前言
作者对于 unordered_map 是一位 beginner.本文对于unordered_map的常用的crud 基本操作,用于供作者回忆和读者学习.
介绍
- unordered_map 是一个key和value 的关联式容器,可以高效的根据key值查找对应的value。
- key 应该是唯一的,key 和 value 的数据类型可以不相同。
- unordered_map 查询单个 key 值的效率比map高,但是查询一定范围内的key值时效率比map低
- unordered_map 是无序的,map是有序的。
- unordered_map 重载了 [] , 可以直接通过 [key] 找到value.
常用操作介绍
主要介绍curd,以及其他好用的函数。
插入元素
// 插入方法 1
un_mp.insert(std::unordered_map<std::string , int>::value_type("test" , 1));
// 插入方法 2
un_mp["test"] = 333;
std::cout << un_mp["test"] << '\n';
明显我们发现第二种插入方法更加的方便 un_map[key] = value
删除元素
un_mp["test"] = 333;
un_mp.erase("test");
std::cout << un_mp["test"] << '\n';
因为我们将 "test" 删除了 ,所以输出的是 0.
注: 如果删除的key 不存在的话 ,那么erase 函数会返回 0 , 其中返回值表示的是删除元素的个数。
查询元素
auto f = un_mp.find("test");
if (f != un_mp.end())
std::cout << f -> second << '\n';
返回的是迭代器的指针 , 如果不存在的话返回 un_map.end()
修改元素
这里推荐的指正修改和 [] 运算符直接修改
- 第一个指针修改
auto f = un_mp.find("test"); std::cout << f -> second << '\n'; - 第二个 [] 运算符修改
un_mp["test"] = 333; 通过key修改value
遍历集合
un_mp["s"] = 1;
un_mp["ss"] = 2;
un_mp["sss"] = 3;
un_mp["ssss"] = 4;
for (auto x : un_mp)
std::cout << x.second << ' ';
防被卡hash
很多比赛都会针对 和 的底层hash值 , 来造数据 ,导致对于单次的查询为 , 而不是 的 , 所以可能对于n个元素的插入,再查询可能是 , 导致超时。 所以给出一种防被卡的方法
struct custom_hash {
static LL splitmix64(LL x) {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
}
size_t operator () (LL x) const {
static const LL FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count(); // 时间戳
return splitmix64(x + FIXED_RANDOM);
}
};
可以这么定义
std::unordered_map<LL, bool, custom_hash> safe_map;
注意: 对于hash函数如果是的话 , 只需要将字符串hash成数值,再进行以上操作 , 修改 重载的 () 的LL---->std::string。
补充
插入元素(不支持 [] 运算符)
mp.insert(std::make_pair(2 , 1));
删除键对应一个值
// 匹配键的值
mp.erase(2);
删除指定键的元素
auto it = mp.find(2); // 删除迭代器指向的元素
if (it != mp.end()) {
mp.erase(it);
}
map 和 unordered_map 的区别
map
- 头文件 : 引入头文件 include<map>
- 优点: 有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作。红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高。
- 缺点:空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点,孩子节点以及红/黑性质,使得每一个节点都占用大量的空间
- 适用处:对于那些有顺序要求的问题,用map会更高效一些。
unordered_map
- 头文件:引入头文件 include<unordered_map>
- 优点:内部实现了哈希表,因此其查找速度是常量级别的。
- 缺点:哈希表的建立比较耗费时间
- 适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
注:对于map 和 unordered_map 的区别 , 我实在不清楚, 所以我直接copy的大佬的。如果大家感兴趣,在下方点击链接可以查看。