#4465. 映射
映射
1、pair:将2个数据组合成一组数据,主要的两个成员变量是 first 和 second。
#include <utility> // pair 定义在 <utility> 头文件中
定义源代码
namespace std {
template <class T1, class T2>
struct pair {
T1 first;
T2 second;
// 默认构造函数
pair() : first(), second() {}
// 带参构造函数
pair(const T1& a, const T2& b) : first(a), second(b) {}
// 拷贝构造函数
template <class U1, class U2>
pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
};
}
pair 是一个 模板类,可以存储 两个不同类型的数据。
T1:第一个元素的类型
T2:第二个元素的类型
1、初始化
#include <utility> // pair 所在头文件
pair<T1,T2> pl; //创建一个空的 pair 对象(使用默认构造) p1.first = 0, p1.second = 0
pair<T1,T2> p1(v1,v2); //创建一个 pair 对象,使用值v1 和 v2 初始化(带参构造函数)
make_pair(vl,v2); // 以 v1 和 v2 的值创建一个新的pair 对象
2、比较
pl<p2; // 两 个pair 对象间的小于运算,其定义遵循字典次序比较 first 和 second
pl == p2; // 如果两个对象的 first 和 second 依次相等,则这两个对象相等;
3、访问
p1.first; // 返回对象p1 中名为first 的公有数据成员
pl.second; // 返回对象 p1 中名为 second 的公有数据成员
常用函数和操作
1 交换两个 pair
pair<int,int> a(1,2), b(3,4);
a.swap(b); // 交换 a 和 b 的内容
// 现在 a = {3,4}, b = {1,2}
2 比较操作
pair 支持按 字典序 比较:
==、!=、<、<=、>、>=
pair<int,int> a(1,5), b(2,3);
cout << (a < b) << endl; // true,因为 a.first < b.first
注意:比较顺序是先比较
first,再比较second。
3 与容器结合
pair 常用于 map、set 或 排序:
#include <vector>
#include <algorithm>
vector<pair<int,int>> v = {{3,1},{2,5},{3,0}};
sort(v.begin(), v.end());
// 排序后 v = {{2,5},{3,0},{3,1}}
4 常用技巧
- 解包 pair
auto [x,y] = make_pair(1,2); // C++17 结构化绑定
- 存储不同类型
pair<string,int> student("Alice", 90);
- 快速生成 pair
make_pair(a,b)
- 在 map 中使用 pair
map<int,string> m;
m.insert({1,"one"});
m.insert(make_pair(2,"two"));
- 排序
// 匿名函数 lamda表达式实现
sort(v.begin(),v.end(),[](对象1,对象2){
排序规则
});
// cmp函数实现
```cpp
bool cmp(对象1,对象2){
排序规则
}
## 2、map(映射):是一种关联容器 通过键可以快速查找对应的值,
map 的每个元素都分为(key)关键字和(value)值两部分,容器中的元素是`按关键字`排序的,
并且不允许有多个元素的关键字相同,map 中的元素是一对数据:<关键字,数值>
```Cpp
namespace std {
template<
class Key,
class T,
class Compare = std::less<Key>, // 默认使用 less<Key> 比较器
class Allocator = std::allocator<std::pair<const Key, T>>
> class map;
}
class Key:表示 键(key)的类型。每个元素在 map 中都有一个唯一的键
class T:表示 值(value)的类型,与键对应的值
class Compare = std::less< Key> 决定 map 的排序规则,默认升序排序
利用greater去实现降序
map<int, string, less< int> > mp_desc; // 升序排序
map<int, string, greater< int> > mp_desc; // 降序排序
常见函数
| 函数名 | 函数说明 |
|---|---|
| find(关键字) | 返回指定关键字元素的位置迭代器,如果不存在返回map.end()。 |
| count(关键字) | 统计指定关键字元素的个数,由于map每个元素的关键字都不相 同,count结果只能是1或者0。 |
| insert(元素) | 插入元素到map中,元素一般是make_pair(关键字,值) |
| erase(关键字/迭代器) | 删除map指定位置或者指定关键字的元素 |
| clear() | 清除map所有元素,size()变0 |
| 运算符[] | 取/赋值map的指定关键字的对应值,类似数组的下标运算 |
| begin() | map的第一个元素(最小)元素的位置,返回第一个元素迭代器(指针) |
| end() | map的结束位置。注意:返回的迭代器是最后一个元素的后面位 置,不是最后一个元素的迭代器。 |
| size() | 元素个数,map的大小,也就是map中已有元素的个数。 |
| empty() | 判断map是否为空,等价于size()是否为0。 |
map的常见种类:
| 容器类型 | 键是否唯一 | 是否有序 | 底层结构 | 查找/插入/删除时间复杂度 | 备注 |
|---|---|---|---|---|---|
map |
唯一 | 有序 | 红黑树 | O(log n) | 默认升序,可用比较器自定义排序 |
multimap |
可重复 | 允许多个相同 key | |||
unordered_map |
唯一 | 无序 | 哈希表 | 平均 O(1),最坏 O(n) | 元素无顺序 |
unordered_multimap |
可重复 | 允许多个相同 key |