一、map
1. 简介
map是STL的一个关联容器,用红黑树数据结构以键(key)值(value)对形式存储数据的容器,其数据类型可以自己定义,每个key在map中只能出现一次,key不能修改,value值可以修改;
注意,在C++中,map的含义映射,而不是地图。map可以将任何基本类型(包括STL容器以及自定义数类型)映射到任何基本类型(包括STL容器以及自定义数类型),也就是将value值映射到对应的key。
2.定义
template <typename _key, typename _value, typename _compare> map;
//定义map类型,是有模板的,他接受三个参数:
//第一个参数是键的数据类型
//第二个参数是值的数据类型
//第三个参数是排序规则,默认按照键的升序排列
case:
//定义了一个叫mp的map类型,并且键值都是int类型
map<int,int>mp;
3.用法
(1)头文件:
#include <map>
(2)初始化
map<key, value> mp;
map<key, value> mp1(mp); //通过已有map初始化一模一样的mp1
map<key, value> mp2(b, e); //其中b、e为同类型map的迭代器,通过b、e区间数据初始化mp2
(3)元素访问
a. 通过STL容器迭代器访问元素
map<key, value>::iterator it;
此时可以通过it->first来访问当前元素的键,it->second来访问对应值:
b. 通过下标[] 和 at() 访问,
示例:
map<char, int> mp;
map['a'] = 18;
mp['c'] = 20;
cout << mp['a']; //输出结果为18
cout << mp.at('c'); //输出结果为20
注意:[ ] 只使用与非 const 修饰的 map,因为[ ]重载不是map的const 成员函数,当[ ]中给到的key不存在于map中,会在map中添加一个对应key默认值的成员,此时修改了map,因此调用const map[]编译会报错;
(4)插入元素
插入元素有两种方法,1)使用下标直接插入; 2)使用insert() 插入元素
注意:当插入的key在map中本就存在,使用下标插入map[key] = newValue会覆盖原有value,但是使用**map.insert(make_pair(key, newValue))**会插入失败,但是不会直接报错,
以map<int, string> student为例
a. 直接插入单值:
student.insert(pair<int, string>(01, "ZhangSan"));
或者:
student.insert(make_pair(01, "ZhangSan"));
b.在使用value_type插入
student.insert(map<int,string>::value_type(1,"student_one"));;
c.在指定位置插入
student.insert(iter,e)
其中iter为student的迭代器, e为对应pair元素
d.插入指定区间元素
student.insert(begin, end); //begin和end为student相同类型map起始和终结位置迭代器
(5)使用erase()删除元素
mp.erase(key);
或者
mp.erase(iter); //iter = mp.find(key)
或者
mp.erase(first, last); //first和last是mp的迭代器
(6)成员函数
函数 | 功能 |
---|---|
empty() | 判断map是否为空,返回bool |
size() | 计算map容器元素数量 |
max_size() | 可以容纳元素最大个数 |
clear() | 清空容器中元素 |
begin() | 返回指向map头部的迭代器 |
end() | 返回指向map末尾的迭代器 |
rbegin() | 返回一个指向map尾部的逆向迭代器 |
rend() | 返回一个指向map头部的逆向迭代器 |
erase(key) | 删除key对应的元素 |
find(key) | 查找key对应元素,返回对应迭代器,不存在返回end() |
swap() | 交换两个map |
count(k) | 查找关键字k出现的次数 |
lower_bound(k) | 返回关键字 >=k 的元素的第一个位置(是一个迭代器) |
upper_bound(k) | 返回关键字>k的元素的第一个位置(是一个迭代器), 如果不存在返回end |
二、unordered_map
1.简介
unordered_map基于哈希表来实现,内部元素无序。对应查找的时间复杂度是O(1)。
头文件:
#include <unordered_map>
2.unordered_map和map的对比
map的优点:(1)map是有序的,按key值排序(2)基于红黑树实现,查找的时间复杂度是O(longn)
map的缺点:空间占用率比较高,
unordered_map的优点:查找效率非常高
unordered_map的缺点:哈希表的建立比较费时
适用的情况:对于查找问题,适用unordered_map会更好一点。
3.使用
unordered_map和map的使用几乎是一致的,只是头文件和定义不同
三、multimap
1.multimap介绍
multmap是关联容器,同样使用红黑树(二叉搜索树)构建,按照特定顺序存储键值对<key、value>,与map以及unordered_map不同的是,multimap可以其中重复使用多个相同的key,即一个key可以对应不同value值;
其中key用于元素排序,默认为升序排列。
2.multimap使用
(1)头文件:
#include <map>
(2)multimap的构造
函数声明 | 功能简介 |
---|---|
explicit multimap (const key_compare& comp =key_compare(), const allocator_type& alloc = allocator_type()); | 默认初始化构造一个空的multimap |
template multimap (InputIterator first, InputIterator last,const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); | 用已有multimap的迭代器first和end指定对应区间中的元素构造multimap |
multimap (const multimap& x); | multimap的拷贝构造 |
(3) 常用函数
函数 | 功能简介 |
---|---|
begin () | 返回第一个元素的迭代器 |
end () | 返回最后一个元素的下一个迭代器 |
begin () const | 返回第一个元素的const迭代器 |
end () const | 返回最后一个元素下一个位置的const迭代器 |
rbegin() | 返回最后一个元素位置的反向迭代器 |
rend() | 返回第一个元素反向迭代器 |
rbegin()const | 返回最后一个元素位置的const反向迭代器 |
rend() const | 返回第一个元素const反向迭代器 |
empty() | 判断map是否为空,返回bool |
size() | 计算map容器元素数量 |
max_size() | 可以容纳元素最大个数 |
clear() | 清空容器中元素 |
swap() | 交换两个map |
find(key) | 查找key对应元素,返回第一个元素的迭代器,不存在返回end() |
insert() | 插入元素,与map相同 |
erase() | 删除元素,与map相同 |
merge() | 将目标multimap中元素合并到当前容器,并清空目标容器中对应元素 |
cout(key) | 对给定的key,统计<key, value>的数量 |
lower_bound(k) | 返回关键字 >=k 的元素的第一个位置(是一个迭代器) |
upper_bound(k) | 返回关键字>k的元素的第一个位置(是一个迭代器), 如果不存在返回end |
equal_range(k) | 返回=k 的迭代器区间[lower_bound(k), upper_bound(k)] |
注意:multimap中没有operator[ ],也没有at()