C++ map/multimap容器超详解

pair对组

在学习map之前我们先了解一下pair对组,因为map中的基本元素就是对组pair

  • pair是将2个数据组合成一组数据,当一个函数需要返回2个数据的时候,就可以选择pair

  • pair是用一个结构体实现的,结构体主要的两个成员变量first和second,分别存储两个数据

pair的创建:

  1. pair<T1,T2> p1(t1,t2);
  2. 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;
}

测试结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_52324409/article/details/121304432
今日推荐