C++ map/ multimap 容器
前言
本文包含map基本概念、map构造和赋值、map大小和交换、map插入和删除、map查找和统计、map容器排序。
1 map 基本概念
简介:
(1)、map 中所有元素都是 pair
(2)、pair 中第一个元素为 key(键值),起到索引作用,第二个元素为 value(实值)
(3)、所有元素都会根据元素的键值自动排序
本质: map/multimap 属于 关联式容器,底层结构是用二叉树实现
优点: 可以根据 key 值快速找到 value 值
map 和 multimap 区别:
(1)、map 不允许容器中有重复 key 值元素
(2)、multimap 允许容器中有重复 key 值元素
2 map 构造和赋值
功能描述: 对 map 容器进行构造和赋值操作
构造:
-
map<T1, T2> mp;
map 默认构造函数 -
map(const map &mp);
拷贝构造函数
赋值:
map& operator=(const map &mp);
重载等号操作符
// map关联式容器构造和赋值
#include <iostream> // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include <map> // 使用map栈容器,需包含头文件map
void printMap(map<int, int>& m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key = " << (*it).first << " value = " << it->second << endl; // 对组,第一个数it->first;第二个数it->second
}
cout << endl;
}
void test01()
{
// 1、默认构造;创建map关联式容器
map<int, int>m; // 成对出现,需写两个参数
m.insert(pair<int, int>(1, 10)); // map关联式容器成对出现,所以需要使用pair对组;pair<int, int>(1, 10)相当于匿名对组,将这个匿名对组放到容器中
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(2, 20));
printMap(m); // 插入时按照key值进行自动排序
// 2、拷贝构造
map<int, int>m2(m);
printMap(m2);
// 3、赋值
map<int, int>m3;
m3 = m2;
printMap(m3);
}
int main() {
test01();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
3 map 大小和交换
功能描述: 统计 map 容器大小以及交换 map 容器
函数原型:
(1)、empty();
判断容器是否为空
(2)、size();
返回容器中元素的数目
(3)、swap(st);
交换两个集合容器
// map关联式容器大小和交换
#include <iostream> // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include <map> // 使用map栈容器,需包含头文件map
void printMap(map<int, int>& m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key = " << (*it).first << " value = " << it->second << endl; // 对组,第一个数it->first;第二个数it->second
}
cout << endl;
}
void test01()
{
// 默认构造;创建map关联式容器
map<int, int>m; // 成对出现,需写两个参数
m.insert(pair<int, int>(1, 10)); // map关联式容器成对出现,所以需要使用pair对组;pair<int, int>(1, 10)相当于匿名对组,将这个匿名对组放到容器中
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(2, 20));
// 1、empty()判断容器是否为空,返回真则为空
if (m.empty())
{
cout << "m为空" << endl;
}
else
{
cout << "m不为空" << endl;
// 2、size()返回容器中元素个数
cout << "m的大小为: " << m.size() << endl; // m的大小为: 3
cout << endl;
}
}
// 3、swap()交换
void test02()
{
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
map<int, int>m2;
m2.insert(pair<int, int>(4, 100));
m2.insert(pair<int, int>(5, 200));
m2.insert(pair<int, int>(6, 300));
cout << "交换前" << endl;
printMap(m);
printMap(m2);
cout << "交换后" << endl;
m.swap(m2);
printMap(m);
printMap(m2);
}
int main() {
test01();
cout << endl;
test02();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
4 map 插入和删除
功能描述: map 容器进行插入数据和删除数据
函数原型:
(1)、insert(elem);
在容器中插入元素
(2)、erase(pos);
删除 pos 迭代器所指的元素,返回下一个元素的迭代器
(3)、erase(key);
删除容器中值为key的元素
(4)、erase(beg, end);
删除区间 [beg,end) 的所有元素 ,返回下一个元素的迭代器
(5)、clear();
清除所有元素
// map关联式容器插入和删除
#include <iostream> // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include <map> // 使用map栈容器,需包含头文件map
void printMap(map<int, int>& m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key = " << (*it).first << " value = " << it->second << endl; // 对组,第一个数it->first;第二个数it->second
}
cout << endl;
}
void test01()
{
// 1、插入
map<int, int> m;
// 第一种插入方式
m.insert(pair<int, int>(1, 10)); // <int, int>模板参数
// 第二种插入方式
m.insert(make_pair(2, 20));
// 第三种插入方式
m.insert(map<int, int>::value_type(3, 30));
// 第四种插入方式
m[4] = 40; // map关联式容器重载了[];不建议使用(插错或不存在)
// []不建议使用插入,用途:可以利用key访问到value
//cout << m[5] << endl; // key = 5 value = 0;如果key不存在,程序会创建一个key为5,value为0的map元素
//cout << m[4] << endl; // 40
printMap(m);
// 2、删除容器开始迭代器元素
m.erase(m.begin());
printMap(m);
// 3、删除key为3的容器
m.erase(3); // 按照key删除
printMap(m);
// 4、删除容器开始迭代器到结束迭代器之间的数据元素
m.erase(m.begin(), m.end());
printMap(m);
// 5、清除
m.clear();
printMap(m); //
}
int main() {
test01();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
总结:map 插入方式很多,记住其一即可
5 map 查找和统计
功能描述: 对 map 容器进行查找数据以及统计数据
函数原型:
(1)、find(key);
查找 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回 set.end()
(2)、count(key);
统计 key 的元素个数
// map关联式容器查找和统计
#include <iostream> // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include <map> // 使用map栈容器,需包含头文件map
void test01()
{
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(3, 40));
// 1、查找key3是否存在
map<int, int>::iterator pos = m.find(3);
if (pos != m.end())
{
cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl; // pos本身就是一个迭代器,解引用后能拿到内部数据
}
else
{
cout << "未找到元素" << endl;
}
// 2、统计key的元素个数
// map关联式容器不允许插入重复key元素;count统计而言,结果要么是0,要么是1
// mulitimap的count统计可能大于1
int num = m.count(3); // count返回结果是一个整形
cout << "num = " << num << endl;
}
int main() {
test01();
cout << endl;
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
6 map 容器排序
(1)、map 容器默认排序规则为按照 key 值进行从小到大排序,掌握如何改变排序规则
(2)、利用仿函数,可以改变排序规则
// map关联式容器排序
#include <iostream> // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include <map> // 使用map栈容器,需包含头文件map
class MyCompare {
public:
//bool operator()(int v1, int v2) {
bool operator()(const int v1, const int v2) const {
// 降序
return v1 > v2;
}
};
void test01()
{
// 默认从小到大排序
// 利用仿函数实现从大到小排序
map<int, int, MyCompare> m;
m.insert(make_pair(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(3, 30));
m.insert(make_pair(4, 40));
m.insert(make_pair(5, 50));
for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
cout << "key:" << it->first << " value:" << it->second << endl;
}
}
int main() {
test01();
cout << endl;
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
总结
(1)、map 中所有元素都是成对出现,插入数据时候要使用对组;
(2)、map 判断是否为空 — empty;
(3)、map 统计大小 — size;
(4)、map 交换容器 — swap;
(5)、map 插入 — insert ;
(6)、map 删除 — erase;
(7)、map 清空 — clear;
(8)、map 查找 — find (返回的是迭代器);
(9)、map 统计 — count (对于map,结果为0或者1);
(10)、利用仿函数可以指定 map 容器的排序规则;
(11)、对于自定义数据类型,map 必须要指定排序规则,同 set 容器。