【STL】关联容器之unordered_map用法总结

       

一、基本原理

        unordered_map是C++标准库提供的关联容器之一,保存的是键值对(key-value),我们可以通过key快速查找到其对应的value。unordered_map底层使用的数据结构是哈希表(hash table),因此在unordered_map中查找、添加或删除元素时间复杂度都是常数时间O(1)。此外,unordered_map中的元素是无序的

       
unordered_map使用场景:

        现在假设有一个寝室501,寝室有4个学生,我们要用一种容器来保存这4个学生的学号和姓名,需求是我要通过学号来查找这个学号对应的姓名。

        此时我们用一个unordered_map来保存,学号作为key,姓名作为value,一个学生的这两个信息作为unordered_map的一个元素pair(pair用法总结),我们可以通过学号来得到对应的姓名。

        也许你会有这样的疑问,为什么要用unordered_map呢,我用一个二维数组不是也一样能存放寝室4个学生的学号和姓名吗?

        是的,存是可以存,但是操作的时间复杂度就不一样了,比如我知道学号"sc0303",我想查找对应的姓名,如果用unordered_map保存的,根据哈希表的特性,只需要O(1)的时间就能查到对应的姓名。如果用的二维数组保存的,需要从头遍历二维数组的第一列,需要O(n)的时间才能查到。这就是使用unordered_map的意义。

        也许你还会有这样的疑问,为什么要用unordered_map呢,我用一个map也一样能存吗?

        用map和unordered_map的区别在于,map基于红黑树,是按关键字有序排列的,unordered_map基于哈希表,是散列存放的(无序)。当你需要进行范围查询“比学号sc0302大的同学的姓名”,那么使用map就更方便,因为map中元素已经按照学号(关键字)有序排好了,但是如果这种场景下使用unordered_map,你要进行范围查找只能一个一个去比较了。在进行等值查询时unordered_map只需要O(1)的时间就能查到,但map却需要O(log(n))的时间,因此等值查询时使用unordered_map更快。

        具体选用哪种容器还是要看使用场景,它们各有优势。

       

       

       

二、用法

       unordered_map中的元素是一对对键值对,类型pair,用法可参考博客pair用法总结
       

初始化

unordered_map<T1,T2>    容器名; T1、T2是类型名,可以是基本数据类型int、double等,也可以是类类型string等
unordered_map<T1,T2>   m1; 创建一个名为m1的空unordered_map,key的类型为T1,value的类型为T2
unordered_map<T1,T2>   m1{p1,p2……}; m1中的元素被初始化为p1,p2……,p1、p2是pair类型
unordered_map<T1,T2>   m1{ {key1,value1},{key2,value2}……}; m1中的元素被初始化为 键值对{key1,value1},{key2,value2}……
unordered_map<T1,T2>   m2(m1); m2中包含和m1一样的元素
unordered_map<T1,T2>   m2=m1; m2中包含和m1一样的元素

程序示例:

pair<string, string> p1("sc0301","小杨");	            // 方式一,创建一个pair名为p1
pair<string, string> p2 = make_pair("sc0302", "小马");	// 方式二,make_pair函数返回一个用"sc0302"和 "小马"初始化的pair
pair<string, string> p3("sc0303", "小王");
pair<string, string> p4("sc0304", "小何");

unordered_map<string, string> m1;                 // 创建一个空unordered_map
unordered_map<string, string> m2{
    p1,p2,p3,p4 };  // 创建一个包含键值对p1、p2、p3、p4的unordered_map
unordered_map<string, string> m3{
    {
   "sc0301","小杨"},{
   "sc0302", "小马"},{
   "sc0303", "小王"},{
   "sc0304", "小何"} }; // 效果同上一句
unordered_map<string, string> m4(m2);   // 创建一个unordered_map,m4中包含和m2一样的元素
unordered_map<string, string> m5 = m2;  // 创建一个unordered_map,m5中包含和m2一样的元素

       

访问元素

访问元素
T2 value = m1[key]; 得到关键字key对应的值value
m1.at(key); 得到关键字key对应的值value
*iter 访问迭代器iter指向的元素
获取迭代器
m1.begin(); 获取指向m1首元素的迭代器
m1.end(); 获取指向m1尾元素的后一个位置的迭代器
m1.rbegin(); 获取指向m1首元素的前一个位置的迭代器
m1.rend(); 获取指向m1尾元素的迭代器
m1.cbegin(); m1.cend(); 含义同上,但获取到的是const_iterator
m1.crbegin(); m1.crend(); 含义同上,但获取到的是const_iterator

程序示例:

string p2_name = m2["sc0302"];	   // 得到学号(关键字)"sc0302"对应的姓名(值)
string p3_name = m2.
  • 14
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于STL中的`map`和`unordered_map`,它们都是关联容器,用于存储键值对。它们之间的主要区别在于底层实现和性能特征。 `map`是基于红黑树实现的有序容器。它按照键的顺序存储元素,并且支持插入、查找和删除操作的平均时间复杂度为O(log n)。因为有序性质,`map`可以提供范围查找和按照键的顺序遍历等功能。 `unordered_map`是基于哈希表实现的无序容器。它使用哈希函数将键映射到桶中,并且支持插入、查找和删除操作的平均时间复杂度为O(1)。由于无序性质,`unordered_map`不能提供范围查找和按照键的顺序遍历等功能,但在大多数情况下具有更好的性能。 下面是它们的一些常见用法示例: 使用`map`: ```cpp #include <iostream> #include <map> int main() { std::map<std::string, int> myMap; // 插入键值对 myMap["Alice"] = 25; myMap["Bob"] = 30; // 查找元素 std::cout << myMap["Alice"] << std::endl; // 输出25 // 遍历所有键值对 for (const auto& pair : myMap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; } ``` 使用`unordered_map`: ```cpp #include <iostream> #include <unordered_map> int main() { std::unordered_map<std::string, int> myMap; // 插入键值对 myMap["Alice"] = 25; myMap["Bob"] = 30; // 查找元素 auto iter = myMap.find("Alice"); if (iter != myMap.end()) { std::cout << iter->second << std::endl; // 输出25 } // 遍历所有键值对 for (const auto& pair : myMap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; } ``` 希望这些示例能帮助你理解`map`和`unordered_map`的用法。如果还有其他问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值