#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 常用技巧

  1. 解包 pair
auto [x,y] = make_pair(1,2); // C++17 结构化绑定
  1. 存储不同类型
pair<string,int> student("Alice", 90);
  1. 快速生成 pair
make_pair(a,b)
  1. 在 map 中使用 pair
map<int,string> m;
m.insert({1,"one"});
m.insert(make_pair(2,"two"));
  1. 排序
// 匿名函数 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