文章内容转载自黑马程序员C++提高编程讲义,如有侵权,请联系作者删除
3.9 map/ multimap容器
3.9.1 map基本概念
简介:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
本质:
- map/multimap属于关联式容器,底层结构是用二叉树实现。
优点:
map和multimap区别:
- map不允许容器中有重复key值元素
- multimap允许容器中有重复key值元素
3.9.2 map构造和赋值
功能描述:
函数原型:
构造:
map<T1, T2> mp;
//map默认构造函数:
map(const map &mp);
//拷贝构造函数
赋值:
map& operator=(const map &mp);
//重载等号操作符
示例:
#include <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; } cout << endl; }
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)); printMap(m);
map<int, int>m2(m); printMap(m2);
map<int, int>m3; m3 = m2; printMap(m3); }
int main() {
test01();
system("pause");
return 0; }
|
总结:map中所有元素都是成对出现,插入数据时候要使用对组
3.9.3 map大小和交换
功能描述:
函数原型:
size();
//返回容器中元素的数目
empty();
//判断容器是否为空
swap(st);
//交换两个集合容器
示例:
#include <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; } cout << endl; }
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));
if (m.empty()) { cout << "m为空" << endl; } else { cout << "m不为空" << endl; cout << "m的大小为: " << m.size() << endl; } }
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();
test02();
system("pause");
return 0; }
|
总结:
- 统计大小 --- size
- 判断是否为空 --- empty
- 交换容器 --- swap
3.9.4 map插入和删除
功能描述:
函数原型:
insert(elem);
//在容器中插入元素。
clear();
//清除所有元素
erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);
//删除区间[beg,end)的所有元素
,返回下一个元素的迭代器。
erase(key);
//删除容器中值为key的元素。
示例:
#include <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; } cout << endl; }
void test01() { map<int, int> m; m.insert(pair<int, int>(1, 10)); m.insert(make_pair(2, 20)); m.insert(map<int, int>::value_type(3, 30)); m[4] = 40; printMap(m);
m.erase(m.begin()); printMap(m);
m.erase(3); printMap(m);
m.erase(m.begin(),m.end()); m.clear(); printMap(m); }
int main() {
test01();
system("pause");
return 0; }
|
总结:
map插入方式很多,记住其一即可
插入 --- insert
删除 --- erase
清空 --- clear
3.9.5 map查找和统计
功能描述:
函数原型:
find(key);
//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);
//统计key的元素个数
示例:
#include <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));
map<int, int>::iterator pos = m.find(3);
if (pos != m.end()) { cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl; } else { cout << "未找到元素" << endl; }
int num = m.count(3); cout << "num = " << num << endl; }
int main() {
test01();
system("pause");
return 0; }
|
总结:
- 查找 --- find (返回的是迭代器)
- 统计 --- count (对于map,结果为0或者1)
3.9.6 map容器排序
学习目标:
- map容器默认排序规则为 按照key值进行
从小到大排序,掌握如何改变排序规则
主要技术点:
示例:
#include <map>
class MyCompare { public: bool operator()(int v1, int v2) { 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();
system("pause");
return 0; }
|
总结:
- 利用仿函数可以指定map容器的排序规则
- 对于自定义数据类型,map必须要指定排序规则,同set容器
3.10 案例-员工分组
3.10.1 案例描述
- 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作
- 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发
- 随机给10名员工分配部门和工资
- 通过multimap进行信息的插入 key(部门编号) value(员工)
- 分部门显示员工信息
3.10.2 实现步骤
- 创建10名员工,放到vector中
- 遍历vector容器,取出每个员工,进行随机分组
- 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
- 分部门显示员工信息
案例代码:
#include<iostream> using namespace std; #include <vector> #include <string> #include <map> #include <ctime>
#define CEHUA 0 #define MEISHU 1 #define YANFA 2
class Worker { public: string m_Name; int m_Salary; };
void createWorker(vector<Worker>&v) { string nameSeed = "ABCDEFGHIJ"; for (int i = 0; i < 10; i++) { Worker worker; worker.m_Name = "员工"; worker.m_Name += nameSeed[i];
worker.m_Salary = rand() % 10000 + 10000; v.push_back(worker); } }
void setGroup(vector<Worker>&v,multimap<int,Worker>&m) { for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++) { int deptId = rand() % 3;
m.insert(make_pair(deptId, *it)); } }
void showWorkerByGourp(multimap<int,Worker>&m) { cout << "策划部门:" << endl;
multimap<int,Worker>::iterator pos = m.find(CEHUA); int count = m.count(CEHUA); int index = 0; for (; pos != m.end() && index < count; pos++ , index++) { cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl; }
cout << "----------------------" << endl; cout << "美术部门: " << endl; pos = m.find(MEISHU); count = m.count(MEISHU); index = 0; for (; pos != m.end() && index < count; pos++, index++) { cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl; }
cout << "----------------------" << endl; cout << "研发部门: " << endl; pos = m.find(YANFA); count = m.count(YANFA); index = 0; for (; pos != m.end() && index < count; pos++, index++) { cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl; }
}
int main() {
srand((unsigned int)time(NULL));
vector<Worker>vWorker; createWorker(vWorker);
multimap<int, Worker>mWorker; setGroup(vWorker, mWorker);
showWorkerByGourp(mWorker);
system("pause");
return 0; }
|
总结:
- 当数据以键值对形式存在,可以考虑用map 或 multimap