pair对组
在学习map之前我们先了解一下pair对组,因为map中的基本元素就是对组pair。
-
pair是将2个数据组合成一组数据,当一个函数需要返回2个数据的时候,就可以选择pair
-
pair是用一个结构体实现的,结构体主要的两个成员变量first和second,分别存储两个数据
pair的创建:
pair<T1,T2> p1(t1,t2);
pair<T1,T2> p2 = make_pair(t1,t2);
T1和T2是两个数据类型,可以是内置数据类型,也可以是自定义数据类型
实例演练:
#include<iostream>
using namespace std;
void text()
{
pair<string, int> p1("张三", 20);//创建方式1
pair<string, int> p2 = make_pair("李四", 25);//创建方式2
//first获取第一个元素,second获取第二个元素
cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl;
cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
}
int main()
{
text();
system("pause");
}
map的基本概念
简介:
- map中所有元素都是pair
- map中的pair第一个元素为key(键值),起索引作用,就相当于数组下标,第二个元素为value(实值)
- map所有元素会根据键值大小自动排序
本质:
- map/multimap属于关联式容器,底层结构是用二叉树实现的
优点:
- 可以根据key值快速找到其对应的value值
map和multimap的区别:
- map不允许容器中有相同的key值元素,value可以相同
- multimap允许容器中有相同的key值元素
使用map/multimap容器需要包含以下头文件:
#include<map>
map的构造和赋值
构造:
map<T1,T2> mp
; 默认构造函数
map(const map& mp)
拷贝构造函数
赋值:
map& operator=(const map& mp);
重载赋值运算符
先定义一个打印输出的函数,之后的测试会经常使用这个函数
void printMap(map<int,string>& mp)
{
for (map<int, string>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << "key值:" << it->first << " value值:" << it->second << endl;
}
cout << endl;
}
测试案例:
void text()
{
map<int, string> m; //默认构造
//insert是map的一个具有插入元素功能的成员函数,之后会详细介绍
//系统会按照key值的大小选择插入位置,默认按key值升序排序
m.insert(pair<int, string>(30, "张三"));
m.insert(pair<int, string>(25, "李四"));
m.insert(pair<int, string>(28, "王五"));
printMap(m);
map<int, string> m2(m); //拷贝构造
map<int, string> m3;
m3 = m; //重载赋值运算符
printMap(m2);
printMap(m3);
}
测试结果:
map的大小和交换
函数原型:
size();
返回容器中元素的个数
empty();
判断容器是否为空
swap();
交换两个容器
测试案例:
void text()
{
map<int, string> m1,m2;
m1.insert(pair<int, string>(1, "张三"));
if (m2.empty())//容器为空empty()返回1,不为空返回0
{
m2.insert(pair<int, string>(2, "李四"));
cout << "m2的大小为:" << m2.size() << endl;
}
else cout << "m2不为空" << endl;
cout << "交换前:" << endl;
printMap(m1);
printMap(m2);
m1.swap(m2); //交换m1,m2
cout << "交换后:" << endl;
printMap(m1);
printMap(m2);
}
测试结果:
map的插入和删除
函数原型:
insert(elem);
在容器中插入元素,elem是一个对组
erase(pos);
删除迭代器pop所指的元素,返回下一个元素的迭代器
erase(pos1,pos2);
删除区间[pos1,pos2)的所有元素,返回pos2的迭代器
erase(key);
删除容器中值为key的元素
clear();
请空所有元素
测试案例:
void text()
{
map<int, string> m;
//插入有4中方式
//方式1
m.insert(pair<int, string>(30, "张三"));
//方式2(最常用)
m.insert(make_pair(25, "李四"));
//方式3(不常用)
m.insert(map<int, string>::value_type(28, "王五"));
//方式4
m[20] = "赵六"; //[]内的是key值,= 后的是value值
//不建议使用[]方式插入元素,[]一般用来访问元素
cout << "打印m[20]的value值: " << m[20] << endl;//如果m[20]不存在,系统会创建一个默认值的m[20]
printMap(m);
//删除
m.erase(m.begin());//删除第一个元素
m.erase(30); //删除key值为20的元素
printMap(m);
m.erase(m.begin(), m.end());//清空,等价于 m.clear();
}
测试结果:
map的查找和统计
函数原型:
find(key);
- 查找键值为key的元素是否存在
- 如果存在返回该元素的迭代器,不存在返回迭代器 end()
count(key);
- 统计键值为key的元素的个数
- map容器中不能插入相同key值的元素,count(key)的值只能为0或1
- multimap容器中可以插入相同key值的元素,count(key)的值可能会大于1
测试案例:
void text()
{
map<int, string> m;
m.insert(make_pair(25, "张三"));
m.insert(make_pair(20, "李四"));
m.insert(make_pair(30, "王五"));
//查找
map<int, string>::iterator pos = m.find(20);
if (pos != m.end())
{
cout << "找到了,其值为" << pos->second << endl;
}
else cout << "未找到" << endl;
//统计
int num = m.count(30);
cout << "key为30的元素的个数:" << num << endl;
}
测试结果:
map容器的排序规则
map容器默认排序规则为按照key值进行升序排序,我们可以利用仿函数改变排序规则,实现降序排序或者对一些自定义数据类型的排序。
下面我们自定义一个学生类,有两个类成员变量学号和年龄,将其作为map容器的key值,然后利用仿函数定义一个排序规则对其排序,规则如下:
- 按照年龄升序排序
- 年龄相同,按照学号降序排序
测试案例:
class Student//学生类
{
public:
int m_num;//学号
int m_age;//年龄
//有参构造,按初始化列表方式赋值
Student(int num,int age):m_num(num), m_age(age){
}
};
class MyCompare//指定排序规则
{
public:
//排序规则,按照年龄从小到大排序,年龄相等按照学号从大到小排序
int operator()(const Student& s1, const Student& s2) const
{
if (s1.m_age == s2.m_age)
return s1.m_num > s2.m_num;
return s1.m_age < s2.m_age;
}
};
void text()
{
//创建指定排序规则 MyCompare 的map容器
map<Student,string,MyCompare> m;
Student s1(1001, 20);
Student s2(1005, 21);
Student s3(1003, 20);
Student s4(1002, 20);
Student s5(1004, 22);
m.insert(make_pair(s1, "张三"));
m.insert(make_pair(s2, "李四"));
m.insert(make_pair(s3, "王五"));
m.insert(make_pair(s4, "赵六"));
m.insert(make_pair(s5, "七七"));
for (map<Student, string>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "姓名:" << it->second << " 学号:" << it->first.m_num
<< " 年龄:" << it->first.m_age << endl;
}
cout << endl;
}
测试结果: