C++ --STL容器之map/multimap使用及案例实现

本文深入探讨了STL中的Map容器特性,包括其基于红黑树的内部结构、数据自动排序功能,以及如何进行初始化、插入自定义数据、使用equal_range、删除和查找操作。同时,通过案例展示了Map在实际应用中的高效性和灵活性。

一Map容器特性

Map是STL的一个关联容器,它提供一对一(key, value)的数据处理能力,
由于这个特性,在我们处理一对一数据的时候提供快速通道.
map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),
这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处;

在这里插入图片描述
包含头文件:

#include<map>

二.常用操作

1.初始化

四种初始化方式如下:
先声明一个map对象 :
map容器模板参数,第一个参数key的类型,第二参数value类型

map<int, int> mymap;

1)用insert函数插入pair数据

//pair.first key值 piar.second value值
mymap.insert(pair<int,int>(10,20));

2).使用make_pair

mymap.insert(make_pair(20, 20));

3).用insert函数插入value_type数据

mymap.insert(map<int, int>::value_type(30,30));

4)用数组方式插入数据,如下:

  • 使用这种方式时,发现如果key不存在,会创建pair插入到map容器中
    如果发现key存在,那么会修改key对应的value。
  • 通过【】方式去访问map中一个不存在key,map会将这个访问的key插入到map中,并且给value一个默认值
mymap[40] = 40;
mymap[10] = 20; 

注意:
在这里插入图片描述
程序示例:

void test01() {

		//map容器模板参数,第一个参数key的类型,第二参数value类型
		map<int, int> mymap;

		//插入数据  pair.first key值 piar.second value值
		//第一种
		pair<map<int, int>::iterator, bool> ret = mymap.insert(pair<int, int>(10, 10));
		if (ret.second) {
			cout << "第一次插入成功!" << endl;
		}
		else {
			cout << "插入失败!" << endl;
		}
		ret = mymap.insert(pair<int, int>(10, 20));
		if (ret.second) {
			cout << "第二次插入成功!" << endl;
		}
		else {
			cout << "插入失败!" << endl;
		}
		//第二种
		mymap.insert(make_pair(20, 20));
		//第三种
		mymap.insert(map<int, int>::value_type(30, 30));
		//第四种
		mymap[40] = 40;
		mymap[10] = 20;
		mymap[50] = 50;
		//发现如果key不存在,创建pair插入到map容器中
		//如果发现key存在,那么会修改key对应的value

		//打印
		for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++) {
			// *it 取出来的是一个pair
			cout << "key:" << (*it).first << " value:" << it->second << endl;
		}

		//如果通过【】方式去访问map中一个不存在key,
		//那么map会将这个访问的key插入到map中,并且给value一个默认值
		cout << " mymap[60]: " << mymap[60] << endl;

		//打印
		for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++) {
			// *it 取出来的是一个pair
			cout << "key:" << (*it).first << " value:" << it->second << endl;
		}

	}

程序执行结果:
在这里插入图片描述

2.map插入自定义数据

如果在map中key存入的是自定义数据,如下所示的,以其默认的排序规则是不能实现的,所以就需要自定义排序方法了。

	class MyKey {
	public:
		MyKey(int index, int id) {
			this->mIndex = index;
			this->mID = id;
		}
	public:
		int mIndex;
		int mID;
	};

程序实现如下:排序用一个仿函数来实现

	//仿函数
	struct mycompare {
		bool operator()(MyKey key1, MyKey key2) const {
			return key1.mIndex > key2.mIndex;
		}
	};

	void test02() {

		map<MyKey, int, mycompare> mymap; //自动排序,自定数据类型,咋排?

		mymap.insert(make_pair(MyKey(1, 2), 10));
		mymap.insert(make_pair(MyKey(4, 5), 20));
		map<MyKey, int, mycompare>::iterator it;
		for (it = mymap.begin(); it != mymap.end(); it++) {
			cout << it->first.mIndex << ":" << it->first.mID << " = " << it->second << endl;
		}
	}

程序执行结果:
在这里插入图片描述

3.map数据使用equal_range

equal_range返回容器中key与keyElem相等的上下限的两个迭代器

	//equal_range
	void test03() {

		map<int, int> mymap;
		mymap.insert(make_pair(1, 2));
		mymap.insert(make_pair(2, 5));
		mymap.insert(make_pair(3, 6));

		//返回类型
		pair<map<int, int>::iterator, map<int, int>::iterator> ret;
		ret = mymap.equal_range(2);
		if (ret.first != mymap.end()) {
			cout << "找到lower_bound :" << (*(ret.first)).first << endl;
		}
		else {
			cout << "没有找到";
		}

		if (ret.second != mymap.end()) {
			cout << "找到upper_bound!" << (*(ret.second)).first << endl;
		}
		else {
			cout << "没有找到";
		}

在这里插入图片描述

4.map删除操作

在这里插入图片描述

5.map查找操作

在这里插入图片描述

三、案例测试

需求如下
公司今天招聘了 5 个员工, 5 名员工进入公司之后,需要指派员工在那个部门工作
人员信息有: 姓名 年龄 电话 工资等组成
通过 Multimap 进行信息的插入 保存 显示
分部门显示员工信息 显示全部员工信息。

程序实现如下:

// Multimap Demo.cpp : 
//multimap 案例
//公司今天招聘了 5 个员工, 5 名员工进入公司之后,需要指派员工在那个部门工作
//人员信息有: 姓名 年龄 电话 工资等组成
//通过 Multimap 进行信息的插入 保存 显示
//分部门显示员工信息 显示全部员工信息
//

#include <iostream>
#include<vector>
#include<string>
#include<map>
using namespace std;

#define SALE_DEPATMENT 1 //销售部门
#define DEVELOP_DEPATMENT 2 //研发部门
#define FINACIAL_DEPATMENT 3 //财务部门

class Worker
{
public:
	Worker() { };
	Worker(string name, string tele, int age, int salary)
		:mName(name), mTele(tele), mAge(age), mSalary(salary) {}
public:
	string mName;
	string mTele;
	int mAge;
	int mSalary;
};

//存放新员工信息
void Create_Worker(vector<Worker>& worker) {
	string sName = "ABCDE_";
	for (int i = 0; i < 5; i++) {
		Worker w;
		w.mName = "员工";
		w.mName += sName[i];
		w.mAge = rand() % 10 + 20;//20-30
		w.mSalary = rand() % 5000 + 10000;
		w.mTele = "010-88888888";

		worker.push_back(w);
	}
}


///员工分组,把员工随机分配不同部门
void WorkerByGroup(vector<Worker>& worker, multimap<int, Worker>& WorkerGroup) {
	for (auto it = worker.begin(); it != worker.end(); it++)
	{
		int department_No = rand() % 3 + 1;
		switch (department_No)
		{
		case(SALE_DEPATMENT):
			WorkerGroup.insert(make_pair(SALE_DEPATMENT, *it));
			break;
		case(DEVELOP_DEPATMENT):
			WorkerGroup.insert(make_pair(DEVELOP_DEPATMENT, *it));
			break;
		case(FINACIAL_DEPATMENT):
			WorkerGroup.insert(make_pair(FINACIAL_DEPATMENT, *it));
			break;
		default:
			break;
		}
	}
}

void ShowWorkerGroup(multimap<int, Worker>& WorkerGroup, int department_id) {
	multimap<int, Worker>::iterator pos = WorkerGroup.find(department_id);
	//当前部门员工总人数
	int count_num = WorkerGroup.count(department_id);
	int num = 0;
	for (auto it = pos; it != WorkerGroup.end() && num < count_num; it++, num++) {
		cout << "id: " << it->first << " Name: " << it->second.mName
			<< " Age: " << it->second.mAge << " Tele: " << it->second.mTele
			<< " Salary: " << it->second.mSalary << endl;
	}
}

//分部门显示
void PrintWorkerByGroup(multimap<int, Worker>& WorkerGroup) {	
	//1 销售部门
	cout << "打印销售部门人员信息:" << endl;
	ShowWorkerGroup(WorkerGroup, SALE_DEPATMENT);
	//2 研发部
	cout << "打印研发部人员信息:" << endl;
	ShowWorkerGroup(WorkerGroup, DEVELOP_DEPATMENT);
	//3 财务部
	cout << "打印财务部人员信息:" << endl;
	ShowWorkerGroup(WorkerGroup, FINACIAL_DEPATMENT);
}

int main()
{
	vector<Worker> vWorker;
	multimap<int, Worker> WorkerGroup;
	//存放新员工信息
	Create_Worker(vWorker);
	WorkerByGroup(vWorker, WorkerGroup);
	//员工分组

	//打印
	PrintWorkerByGroup(WorkerGroup);
}

程序执行结果:
在这里插入图片描述

C++ STL中的mapmultimap是关联容器,用于存储键值对(key-value pairs),其中每个键(key)唯一对应一个值(value)。 map是一个有序容器,根据键的大小进行自动排序,默认按照键的升序进行排序。每个键只能在map中出现一次,如果尝试插入具有相同键的元素,新元素将替代旧元素。 multimap也是一个有序容器,与map不同的是,它允许多个具有相同键的元素存在。多个具有相同键的元素将按照插入的顺序进行存储,而不会自动排序。 这两个容器都提供了一系列的操作函数,如insert、erase、find等,用于插入、删除和查找元素。 以下是一个使用map的简单示例: ```cpp #include <iostream> #include <map> int main() { std::map<std::string, int> scores; scores.insert(std::make_pair("Alice", 90)); scores.insert(std::make_pair("Bob", 80)); scores.insert(std::make_pair("Charlie", 70)); // 查找并输出Bob的分数 std::cout << "Bob's score: " << scores["Bob"] << std::endl; // 遍历并输出所有键值对 for (const auto& pair : scores) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; } ``` 上述示例中,我们创建了一个存储string类型键和int类型值的map容器scores。通过insert函数依次插入了三个键值对。然后我们通过scores["Bob"]来获取Bob的分数,并输出结果为80。 接着我们使用范围-based for循环遍历map中的所有键值对,并输出每个键值对的键和值。 multimap的用法与map类似,只是它允许多个具有相同键的元素存在。 这些关联容器在查找和插入操作上具有较高的效率,特别适用于需要根据键进行快速查找的场景。在实际应用中,你可以根据自己的需求选择适合的容器类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值