一、基本知识
在C++的标准库中 map 实现了哈希表的功能
1、简介
- map 中所有元素都是 pair (对组)
- pair 中第一个元素为key(键值),起到索引作用,第二个元素为 value (实值)
- 所有元素都会根据元素的键值(key),来自动排序
2、本质
- map/multimap 属于关联式容器,底层结构是用二叉树实现
3、优点
- 可以根据key值快速找到value值
4、map 和 multimap 的区别
- map 不允许容器中有重复的 key 值元素,而multimap容器则可以
二、基本操作
1、map 容器的构造和赋值
(1)、构造
- map<T1, T2> m1 ; // 默认构造函数
- map(const map &m1) ; //拷贝构造函数
(2)、赋值
- map& operator=(const map &m1) ; // 重载等号操作符
#include<iostream>
#include<map>
#include<string>
using namespace std;
void PrintValue(const map<int, int>&m)
{
for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
{
cout << "key= " << (*it).first << " value= " << it->second << endl;
}
cout << endl;
}
void Test01()
{
// map 容器中都是成对的值,可以用隐式的pair来进行赋值
map<int, int>m1;
m1.insert(pair<int, int>(1, 100));
m1.insert(pair<int, int>(2, 200));
m1.insert(pair<int, int>(8, 800));
m1.insert(pair<int, int>(6, 600));
PrintValue(m1);
//拷贝构造
map<int, int>m2(m1);
//赋值
map<int, int>m3;
m3 = m1;
// 交换两个容器
m2.swap(m1);
}
int main()
{
Test01();
cin.get();
}
2、插入、删除、查找、统计
#include<iostream>
#include<map>
#include<string>
using namespace std;
void PrintValue(const map<int, int>&m)
{
for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
{
cout << "key= " << (*it).first << " value= " << it->second << endl;
}
cout << endl;
}
void Test01()
{
map<int, int>m1;
// 用pair来进行插入
m1.insert(pair<int, int>(1, 100));
// 用make_pair来进行插入
m1.insert(make_pair(6, 900));
//值类型插入
m1.insert(map<int, int>::value_type(2, 200));
// 用中括号的方式来进行插入
m1[5] = 500; // 不建议使用该方式插入数值,但是可以使用其key来访问value
PrintValue(m1);
// find(key) 查找key是否存在,存在则返回元素的迭代器,否则返回set.end()
// 需要用一个迭代器来接受查找返回的值
map<int, int>::iterator pos = m1.find(6);
if (pos != m1.end())
{
cout << "key的值为:" << (*pos).first << " " << "value的值为:" << pos->second << endl;
}
else
{
cout << "未找到该值" << endl;
}
// 统计key值的数量
// 对于map而言,其结果为0或1
int num = m1.count(1);
// 删除
m1.erase(m1.begin()); //删除第一个元素
m1.erase(2); // 删除key为2的元素,以key的方式来删除
// 清空
m1.erase(m1.begin(), m1.end());
m1.clear();
}
int main()
{
Test01();
cin.get();
}
3、map容器排序
(1)、内置数据类型默认是按照key的值从小到大来进行排序,可以利用仿函数来修改其排序规则
#include<iostream>
#include<map>
#include<string>
using namespace std;
class MyCompare
{
public:
bool operator()(int v1, int v2)
{
//按照从大到小的规则进行排序
return v1 > v2;
}
};
void PrintValue(const map<int, int,MyCompare>&m)
{
for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
{
cout << "key= " << (*it).first << " value= " << it->second << endl;
}
cout << endl;
}
void Test01()
{
map<int, int,MyCompare>m1;
m1.insert(make_pair(1, 10));
m1.insert(make_pair(2, 20));
m1.insert(make_pair(6, 30));
m1.insert(make_pair(4, 50));
PrintValue(m1);
}
int main()
{
Test01();
cin.get();
}
(2)、自定义数据类型,必须要指定其排序规则,否则无法进行插入。
#include<iostream>
#include<map>
#include<string>
using namespace std;
class Person
{
public:
string m_Name;
int m_Age;
int m_Score;
Person(string name, int age, int score)
{
m_Name = name;
m_Age = age;
m_Score = score;
}
};
class MyCompare
{
public:
bool operator()(const Person &p1,const Person &p2)
{
// 按照分数从高到底排序
return p1.m_Score > p2.m_Score;
}
};
void Test01()
{
map<Person,string,MyCompare>m1;
Person p1("A", 20, 89);
Person p2("B", 22, 100);
Person p3("G", 10, 80);
Person p4("R", 18, 95);
Person p5("K", 29, 99);
m1.insert(make_pair(p1, "第1高中"));
m1.insert(make_pair(p2, "第2高中"));
m1.insert(make_pair(p3, "第3高中"));
m1.insert(make_pair(p4, "第4高中"));
m1.insert(make_pair(p5, "第5高中"));
for (map<Person, string, MyCompare>::iterator it = m1.begin(); it != m1.end(); it++)
{
cout << "姓名:" << (*it).first.m_Name << " 分数:" << (*it).first.m_Score << " 年龄:" << (*it).first.m_Age << " 学校:" << it->second << endl;
}
}
int main()
{
Test01();
cin.get();
}