1.stack容器
1.1基本概念
stack是一种先进后出的数据结构,只有一个出口。而且栈不允许有遍历操作。数据入栈、出栈的一端为栈顶,另一端为栈底。(可以想象成弹夹)
1.2stack常用接口
构造函数:
1> stack stk; //stack采用模板类实现,stack对象的默认构造函数形式
2> stack(const stack &stk); //拷贝构造函数
赋值操作:
3> stack& operator=(const stack &stk); //重载等号操作符
数据存取:
4> void push(elem); //向栈顶添加元素
5> void pop(); //从栈顶移除第一个元素
6> top(); //返回栈顶元素
大小操作:
7> empty(); //判断堆栈是否为空
8> size(); //返回栈的大小
void test14()
{
stack<int> stk; //默认构造
for (int i = 0; i < 10; i++)
{
stk.push(i); //push()从栈顶添加元素
}
stack<int> stk1(stk); //拷贝构造函数
stack<int> stk2;
stk2 = stk1; //重载等号操作符赋值
stk.pop(); //删除栈顶元素
cout << "栈顶元素:" << stk.top() << endl; //返回8。top返回栈顶元素
if (stk1.empty())
{
cout << "stk1为空" << endl;
}
else
{
cout << "stk1非空" << endl;
}
cout << "stk2大小:" << stk2.size() << endl;
}
2. queue容器
2.1 queue的基本概念
queue是一种先进先出的数据结构,它有两个出口。(可以想成排队买饭)
队列容器允许从一端新增数据,从另一端移除数据
队列中只有队头和队尾可以被外界使用,所以队列也不可以遍历
队列中进数据为入队(push)。出数据为出队(pop)。入队一端为队尾(back),出队一端为队头(front)。判断为空empty(),大小size()。
2.2queue常用接口
构造函数:
1> queue< T > que; //queue采用模板类实现,queue对象的默认构造形式
2> queue(const queue< T > &que); //拷贝构造函数
赋值操作:
3> queue& operator = (const queue< T > &que); //重载等号操作符
数据存取:
4> void push(elem); //往队尾添加元素
5> void pop(); //从队头移除第一个元素
6> back(); //返回最后一个元素
7> front(); //返回第一个元素
大小操作
8>bool empty(); //判断堆栈是否为空
9> size(); //返回栈大小
void test15()
{
queue<int> que; //默认构造函数
for (int i = 0; i < 5; i++)
{
que.push(i); //push 入队操作
}
queue<int> que1(que); //拷贝构造函数
queue<int> que2 = que1; //重载等号赋值
if (!que1.empty())
{
que1.pop(); //出队
cout << "que1的队尾元素:" << que1.back() << endl;
cout << "que1的队首元素:" << que1.front() << endl;
cout << "que1的大小:" << que1.size() << endl;
}
else
{
cout << "que1为空!" << endl;
}
}
3.list容器
3.1 list基本概念
功能:将数据链式存储。
链表(list):是一种在物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
链表组成:链表由一系列的结点组成。
结点组成:一个是存储数据的数据域,一个是存储下一个结点的地址的指针域。
STL中链表为带头节点的双向循环链表(最后一个结点的next指向头结点)。
链表优点:可以在任意位置进行快速插入和删除元素,不像数组必须要先删除后移动,只用改指针,效率更高。而且采用动态内存分配,不会造成内存浪费和溢出
链表缺点:遍历效率低,占用空间会比较大。
由于链表存储方式并不是连续的内存空间,所以链表list中的迭代器只支持前移和后移,所以是一个双向迭代器。
list还有一个重要的性质,插入和删除操作都不会造成原有list迭代器的失效,这在vector中是不成立的。(vector中指向某元素的迭代器如果在进行插入删除操作后,vector容器又重新开辟新空间,那么显然这个迭代器还指向原有地址便会失效,在list中就不会出现这种状况,除非指向的元素被删除)
总结:list与vector是两个最常用的容器,各有优缺点!
3.2list的构造函数
功能:创建list容器
函数原型:
1> list list; //list采用模板类实现,默认构造
2> list(beg,end); //构造函数将[beg,end)区间中的元素拷贝给本身
3> list(n,elem); //构造函数将n个elem拷贝给本身
4> list(cosnt list< T > &lst); //拷贝构造函数
void ListPrintf(const list<int> &lst)
{
for (list<int>::const_iterator it = lst.begin(); it != lst.end(); it++)
{
cout << *it << "\t";
}
cout << endl;
}
void test16()
{
list<int> L; //默认构造函数
for (int i = 0; i < 5; i++)
{
L.push_back(i);
}
cout << "L:";
ListPrintf(L);
list<int> L1(L.begin(), L.end()); //使用区间构造
cout << "L1:";
ListPrintf(L1);
list<int> L2(3, 8); //3个8
cout << "L2:";
ListPrintf(L2);
list<int> L3(L2); //拷贝构造
cout << "L3:";
ListPrintf(L3);
}
3.3list赋值和交换
功能:给list容器进行赋值,以及交换list容器。
函数原型:
1> assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身
2> assign(n, elem); //将n个elem拷贝赋值给本身
3> list& operator=(const list &lst); //重载等号操作符
4> swap(lst); //将lst与本身的元素互换
void test17()
{
list<int> L(3, 8);
cout << "L:";
ListPrintf(L); //ListPrintf()函数前面的示例有实现
list<int> L1;
L1.assign(L.begin(),L.end()); //使用assign(beg,end)函数赋值
cout << "L1:";
ListPrintf(L1);
list<int> L2;
L2.assign(5, 6); //使用assign(n,elem)函数赋值
cout << "L2:";
ListPrintf(L2);
list<int> L3;
L3 = L2; //使用等号赋值
cout << "L3:";
ListPrintf(L3);
L3.swap(L1); //使用swap函数交换L1与L3
cout << "L1与L3交换后!" << endl;
cout << "L1:";
ListPrintf(L1);
cout << "L3";
ListPrintf(L3);
}
3.4list大小操作
功能:对list容器的大小进行操作
函数原型:
1> int size(); //返回容器的元素个数
2> bool empty(); //判断容器是否为空
3> resize(num); //重新指定容器的长度为num,若容器变长,则用默认值0填充,若变短,则末尾超出的元素被删除
4> resize(num, elem); //重新指定容器长度,效果与前面一样,只不过默认值由0变为可以指定的elem
void test18()
{
list<int> L(5, 8);
if (!L.empty())
{
cout << "L的大小为:" << L.size() << endl;
cout << "L的大小改为1!" << endl;
L.resize(1);
cout << "L:";
ListPrintf(L);
cout << "L的大小改为10!" << endl;
L.resize(10, 6);
cout << "L:";
ListPrintf(L);
}
else
{
cout << "L为空!" << endl;
}
}
3.5list插入和删除
功能:对list容器进行数据的插入和删除
函数原型:
1> push_back(elem); //在容器尾部加入一个元素
2> pop_back(); //删除容器中最后一个元素
3> push_front(elem); //在容器开头插入一个元素
4> pop_front(); //从容器开头移除一个元素
5> insert(pos, elem); //在pop位置插入elem元素的拷贝,返回新数据的位置(返回迭代器)
6> insert(pos, n, elem); //在迭代器pos位置插入n个元素elem
7> insert(pos, beg, end); //在迭代器pos位置插入[beg, end)区间的数据,无返回值
8> clear(); //清空容器所有数据
9> erase(beg, end); //删除[beg, end)区间的数据,返回下一个数据所在位置
10> erase(pos); //删除pos位置的数据,返回下一个数据的位置
11> remove(elem);//删除容器中所有与elem值匹配的元素
void test19()
{
list<int> L;
for (int i = 1; i <= 3; i++)
{
L.push_back(i);
L.push_front(i);
}
ListPrintf(L);
L.pop_back(); //删除容器最后一个元素
L.pop_front(); //删除容器第一个元素
ListPrintf(L);
L.insert(L.begin(), 10); //在容器头部添加一个元素10
ListPrintf(L);
L.insert(L.end(), 3, 10); //在容器尾部添加三个10
ListPrintf(L);
list<int> L1(2, 8);
list<int>::iterator it = L1.end();
it--;
L.insert(L.end(), L1.begin(), it); //可见STL中凡是与区间相关的都是左闭右开
ListPrintf(L);
L.remove(2); //删除所有与2匹配的结点
ListPrintf(L);
L.erase(L.begin());
ListPrintf(L);
L.clear();
cout << "L.size:" << L.size() << endl;
}
3.6 list数据存取
功能:对list容器中数据进行存取
函数原型:
1> front(); //返回第一个元素
2> back(); //返回最后一个元素
list不支持at函数以及[]是因为底层实现原因。list是链表,结点之间的地址不是连续的,而且list只支持双向迭代器,不能跳跃式访问。
void test()
{
list<int>::iterator it;
it++;
//it = it + 3; //报错!可见该迭代器不支持跳跃式访问
}
void test20()
{
list<int> L;
for (int i = 0; i < 5; i++)
{
L.push_back(i);
}
ListPrintf(L);
//0 1 2 3 4
cout << "L第一个元素是:" << L.front() << endl; //0
L.back() = 10;
ListPrintf(L);
//0 1 2 3 10
}
3.7list反转和排序
功能:将容器中的元素反转,以及将容器中的数据进行排序
函数原型:
1> reverse(); //反转链表
2> sort(); //链表排序
注意:这里sort函数用法与前面queue之中不同,凡是不支持随机迭代器的容器,不可以用标准算法,但是这些容器内部会提供一些算法(成员函数)。如果要实现降序排列,就要写个类似MyCompare函数,并把函数名当参数传入sort函数中。
bool MyCompare(int v1, int v2)
{
return v1 > v2;
}
class MC
{
public:
bool operator()(int v1, int v2)
{
return v1 > v2;
}
};
void test21()
{
list<int> L;
for (int i = 0; i < 5; i++)
{
L.push_back(rand());
}
cout << "L:";
ListPrintf(L);
cout << "反转后L:";
L.reverse();
ListPrintf(L);
cout << "从小到大排序:";
L.sort();
ListPrintf(L);
//降序排列
L.sort(MC());
//L.sort(MyCompare);
ListPrintf(L);
}
3.8排序案例
对于自定义数据类型,如果要进行排序需要自己制定排序规则,使用函数回调
函数回调见https://www.cnblogs.com/danshui/archive/2012/01/02/2310114.html
案例描述:将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高。
排序规则:按照年龄进行升序排列,如果年龄相同按身高进行降序
实现:
class Person
{
public:
Person(string name, int height, int age) :m_Name(name), m_Height(height), m_Age(age) {
}
string m_Name;
int m_Height;
int m_Age;
};
bool PerCompare(Person p1, Person p2)
{
if (p1.m_Age == p2.m_Age)
{
return p1.m_Height > p2.m_Height;
}
else
{
return p1.m_Age < p2.m_Age;
}
}
void test22()
{
list<Person> L;
Person p1("刘备", 160, 35);
Person p2("关羽", 170, 35);
Person p3("张飞", 159, 35);
Person p4("马超", 180, 35);
Person p5("赵云", 176, 22);
Person p6("黄忠", 155, 55);
L.push_back(p1);
L.push_back(p2);
L.push_back(p3);
L.push_back(p4);
L.push_back(p5);
L.push_back(p6);
for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
{
cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << " 身高:" << it->m_Height << endl;
}
cout << "年龄升序,年龄相同身高降序排序后:" << endl;
L.sort(PerCompare);
for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
{
cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << " 身高:" << it->m_Height << endl;
}
}
4.set/multiset容器
4.1set基本概念
简介:所有元素插入时自动排序。
本质:set/multiset是关联容器,底层由二叉树实现。
set/multiset区别:set不允许容器中有重复元素。multiset允许容器中有重复元素。
4.2set构造函数与赋值
功能:创建set容器以及赋值
函数原型:
构造:
1> set st; //默认构造函数
2> set(const set &st); //拷贝构造函数
赋值:
3> set& operator=(const set &st); //重载等号操作符
void SetPrintf(const set<int> &s)
{
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << "\t";
}
cout << endl;
}
void test23()
{
set<int> s; //默认构造
s.insert(1);
s.insert(22);
s.insert(3);
s.insert(44);
s.insert(5);
cout << "s:";
SetPrintf(s);
set<int> s1(s); //拷贝构造
cout << "s1:";
SetPrintf(s1);
set<int> s2;
s2 = s; //重载等号操作符
cout << "s2:";
SetPrintf(s2); //会自动排序
}
4.3set大小和交换
功能描述:统计set容器的大小以及交换set容器
函数原型:
注意:set不支持resize(),因为如果支持,假如利用resize增大容器大小,那么填充的便会重复,与set要求不符!
1> size(); //返回容器中元素的数目
2> empty(); //判断容器是否为空
3> swap(st); //交换两个集合容器
void test24()
{
set<int> s1;
set<int> s2;
for (int i = 0; i < 5; i++)
{
s1.insert(i);
s2.insert(i + 5);
}
cout << "s1:";
SetPrintf(s1);
cout << "s2:";
SetPrintf(s2);
if (!s1.empty())
{
cout << "s1大小:" << s1.size() << endl;
s1.swap(s2);
}
else
{
cout << "s1为空!" << endl;
}
cout << "s1、s2交换后:" << endl;
cout << "s1:";
SetPrintf(s1);
cout << "s2:";
SetPrintf(s2);
}
4.4set插入和删除
功能描述:set容器进行插入数据和删除数据
函数原型:
1> insert(elem); //在容器中插入元素
2> clear(); //清除所有元素
3> erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
4> erase(beg, end); //删除区间[beg, end)的所有元素,返回下一个元素的迭代器
5> erase(elem); //删除容器中值为elem的元素
void test25()
{
set<int> s;
for (int i = 0; i < 5; i++)
{
s.insert(i);
}
cout << "s:";
SetPrintf(s);
//s:0 1 2 3 4
cout << "删除值为3的结点!" << endl;
s.erase(3);
SetPrintf(s);
//0 1 2 4
set<int> s1(s);
cout << "s1:";
SetPrintf(s1);
//s1:0 1 2 4
cout << "删除s1!" << endl;
s1.erase(s1.begin(),s1.end());
cout << "s1.size:" << s1.size() << endl;
//s1.size:0
cout << "删除s的第二个元素!" << endl;
set<int>::iterator it = s.begin();
s.erase(++it);
cout << "s:";
SetPrintf(s);
//s:0 2 4
cout << "删除s:";
s.clear();
SetPrintf(s);
}
4.5set查找和统计
功能:对set容器进行查找数据以及统计数据。
函数原型:
1> find(key); //查找key是否存在,返回该键的元素的迭代器;若不存在,返回set.end()。
2> count(key); //统计key的元素个数。
void test26()
{
set<int> s;
for (int i = 0; i < 5; i++)
{
s.insert(i);
}
cout << "s:";
SetPrintf(s);
cout << "值为3的后一结点的值:";
cout << *(++s.find(3)) << endl;
//值为3的后一结点的值:4
cout << "值为10的个数:";
cout << s.count(10) << endl;
//值为10的个数:0
}
4.6set与multiset的区别
区别:
1> set不可以插入重复数据,而multiset可以。
2> set插入数据的同时会返回插入结果,表示插入是否成功。
3> multiset不会检测数据,因此可以插入重复数据。
void test27()
{
set<int> s;
//可以通过看定义发现insert的返回类型为pair
pair<set<int>::iterator, bool> ret = s.insert(10);
if (ret.second)
{
cout << "插入成功!" << endl;
}
else
{
cout << "插入失败!" << endl;
}
pair<set<int>::iterator, bool> ret1 = s.insert(10);
if (ret1.second)
{
cout << "插入成功!" << endl;
}
else
{
cout << "插入失败!" << endl;
}
multiset<int> mst;
mst.insert(10);
mst.insert(10);
for (multiset<int>::iterator it = mst.begin(); it != mst.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//插入成功!
//插入失败!
//10 10
4.7pair对组创建
功能:成对出现的数据,利用对组可以返回两个数据。
两种创建方式:
1> pair<type, type> p (value1, value2);
2> pair<type, type> p = make_pair(value1, value2);
void test28()
{
pair<int, int> p(1, 100);
pair<int, int>p1 = make_pair(2, 101);
cout << p.first << " " << p.second << endl;
cout << p1.first << " " << p1.second << endl;
}
4.8set容器排序
目标:set会自动从小到大排序,学会如何修改排序规则。
技术:使用仿函数
注意事项:
1> 因为set在插入时就开始排序了,所以要改排序规则必须在插入之间。
2> 自定义数据类型必须指定排序规则。
class Mycompare
{
public:
bool operator()(int v1, int v2)
{
return v1 > v2;
}
};
void test29()
{
set<int> s;
s.insert(1);
s.insert(7);
s.insert(3);
s.insert(0);
s.insert(5);
cout << "s:";
SetPrintf(s);
set<int, Mycompare> s1;
s1.insert(1);
s1.insert(7);
s1.insert(3);
s1.insert(0);
s1.insert(5);
cout << "s1:";
for (set<int, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << "\t";
}
}
//s:0 1 3 5 7
//s1 : 7 5 3 1 0
关于自定义数据类型
class Person1
{
public:
Person1(string name, int age) :m_Name(name), m_Age(age) {
}
string m_Name;
int m_Age;
};
class Mycompare1
{
public:
bool operator()(const Person1 &p1, const Person1 &p2)
{
return p1.m_Age > p2.m_Age;
}
};
void test30()
{
set<Person1,Mycompare1> s;
Person1 p1("张飞", 10);
Person1 p2("刘备", 6);
Person1 p3("关羽", 8);
Person1 p4("曹操", 20);
Person1 p5("刘秀", 80);
s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);
s.insert(p5);
for (set<Person1, Mycompare1>::iterator it = s.begin(); it != s.end(); it++)
{
cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
}
}
//姓名:刘秀 年龄:80
//姓名:曹操 年龄:20
//姓名:张飞 年龄:10
//姓名:关羽 年龄:8
//姓名:刘备 年龄:6
5.map/multimap容器
5.1 map基本概念
简介:
1> map中所有元素都是pair。所以插入操作一定要使用对组pair。
2> pair中第一个元素为key(键),第二个元素为value(实值)。
3> 所有元素都会根据元素的键值自动排序。(key可以起到索引作用)
本质:
1> map/multimap都是关联式容器,底层结构由二叉树实现。
优点:
1> 可以根据key值快速找到value值。
map与multimap的区别:
1> map不允许容器中由重复的key值元素。
2> multimap允许容器中由重复的key值元素。
map高性能高效率,使用频率仅次于list与vector
5.2 map构造和赋值
功能:对map容器进行构造和赋值操作。
函数原型:
构造:
1> map<T1, T2> mp; //map默认构造函数
2> map(const map &mp); //拷贝构造函数
赋值:
1> map& operator=(const map &mp); //重载等号操作符
void MapPrintf(const map<string, int> &m)
{
for (map<string, int>::const_iterator it = m.begin(); it != m.end(); it++)
{
cout << "姓名:" << it->first << " 年龄:" << it->second << endl;
}
cout << endl;
}
void test31()
{
map<string, int> m; //默认构造函数
m.insert(pair<string, int>("张飞", 10));
m.insert(pair<string, int>("刘备", 6));
m.insert(pair<string, int>("关羽", 8));
m.insert(pair<string, int>("曹操", 20));
m.insert(pair<string, int>("刘秀", 80));
MapPrintf(m);
//按照键值的大小自动排序
//姓名:曹操 年龄:20
//姓名:关羽 年龄:8
//姓名:刘备 年龄:6
//姓名:刘秀 年龄:80
//姓名:张飞 年龄:10
map<string, int> m1(m); //拷贝构造函数
MapPrintf(m1);
map<string, int> m2;
m2 = m; //等号操作符重载,实现赋值操作
MapPrintf(m2);
}
5.3map大小和交换
功能:统计map容器大小以及交换map容器
函数原型:
1> size(); //返回容器中元素的数目
2> empty(); //判断容器是否为空
3> swap(); //交换两个集合容器
void MapPrintf(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 test32()
{
map<int, int> m; //默认构造函数
m.insert(pair<int, int>(5, 10));
m.insert(pair<int, int>(3, 6));
m.insert(pair<int, int>(4, 8));
m.insert(pair<int, int>(2, 4));
m.insert(pair<int, int>(1, 2));
MapPrintf(m);
//key:1 value:2
//key:2 value:4
//key:3 value:6
//key:4 value:8
//key:5 value:10
map<int, int> m1; //默认构造函数
m1.insert(pair<int, int>(6, 12));
m1.insert(pair<int, int>(8, 16));
m1.insert(pair<int, int>(10, 20));
m1.insert(pair<int, int>(9, 18));
m1.insert(pair<int, int>(7, 14));
MapPrintf(m1);
//key:6 value:12
//key:7 value:14
//key:8 value:16
//key:9 value:18
//key:10 value:20
if (!m.empty())
{
cout << "m的大小:" << m.size() << endl;
//m的大小:5
m.swap(m1);
}
else
{
cout << "m为空!" << endl;
}
cout << "m、m1交换后!" << endl;
MapPrintf(m);
//key:6 value:12
//key:7 value:14
//key:8 value:16
//key:9 value:18
//key:10 value:20
MapPrintf(m1);
//key:1 value:2
//key:2 value:4
//key:3 value:6
//key:4 value:8
//key:5 value:10
}
5.4map插入和删除
功能:map容器进行插入数据和删除数据
函数原型:
1> insert(elem); //在容器中插入元素
不建议用第四种,因为如果插入时没给value,它会自动创建一个并且值为0。而且如果key值错误重复的话,会覆盖key值对应的原有value值,所以一般用于访问。
//第一种插入
m.insert(pair<int, int>(5, 10));
//第二种插入
m.insert(make_pair(3, 6));
//第三种插入
m.insert(map<int, int>::value_type(4, 8));
//第四种插入
m[2] = 4;
2> clear(); //清除所有元素
3> erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
4> erase(beg, end); //删除区间[beg, end)的所有元素,返回下一个元素的迭代器
5> erase(key); //删除容器中值为key的元素
void test33()
{
map<int, int> m;
//第一种插入
m.insert(pair<int, int>(5, 10));
//第二种插入
m.insert(make_pair(3, 6));
//第三种插入
m.insert(map<int, int>::value_type(4, 8));
//第四种插入
m[2] = 4;
m.insert(pair<int, int>(1, 2));
MapPrintf(m);
//key:1 value:2
//key:2 value:4
//key:3 value:6
//key:4 value:8
//key:5 value:10
cout << "删除键为3的元素!" << endl;
m.erase(3);
MapPrintf(m);
//key:1 value:2
//key:2 value:4
//key:4 value:8
//key:5 value:10
cout << "删除第一个元素!" << endl;
m.erase(m.begin());
MapPrintf(m);
//key:2 value:4
//key:4 value:8
//key:5 value:10
cout << "清空!" << endl;
m.clear();
cout << "m.size:" << m.size() << endl;
//m.size:0
}
5.5map的查找和统计
功能:对map容器进行查找数据以及统计数据
函数原型:
1> find(key); //查找key是否存在,返回该键的元素的迭代器;若不存在,返回set.end()。
2> count(key); //统计key的元素个数
void test34()
{
map<int, int> m;
m.insert(pair<int, int>(5, 10));
m.insert(pair<int, int>(3, 6));
m.insert(pair<int, int>(4, 8));
m.insert(pair<int, int>(2, 4));
m.insert(pair<int, int>(1, 2));
cout << "m:" << endl;
MapPrintf(m);
cout << "查找key为4的value:" << m.find(4)->second << endl;
//查找key为4的value:8
cout << "key为3的元素个数:" << m.count(3) << endl;
//key为3的元素个数:1
map<int, int>::iterator it = m.find(7);
if (it == m.end())
{
cout << "找不到!" << endl;
}
}
3.6map容器排序
目标:map默认按照key值进行排序,如何修改排序规则。
技术:使用仿函数!
//Key降序
class Mycompare2
{
public:
bool operator()(int v1, int v2)
{
return v1 > v2;
}
};
class Person2
{
public:
Person2(string name, int age) :m_Name(name), m_Age(age) {
}
string m_Name;
int m_Age;
};
//自定义类型
class Mycompare3
{
public:
bool operator()(Person2 v1, Person2 v2)
{
return v1.m_Age > v2.m_Age;
}
};
void test35()
{
map<int, int, Mycompare2> m;
m.insert(pair<int, int>(5, 10));
m.insert(pair<int, int>(3, 6));
m.insert(pair<int, int>(4, 8));
m.insert(pair<int, int>(2, 4));
m.insert(pair<int, int>(1, 2));
for(map<int, int, Mycompare2>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key:" << it->first << " value:" << it->second << endl;
}
cout << endl;
Person2 p1("张飞", 10);
Person2 p2("刘备", 6);
Person2 p3("关羽", 8);
Person2 p4("曹操", 20);
Person2 p5("刘秀", 80);
map<Person2, int, Mycompare3> m1;
m1.insert(pair<Person2, int>(p1, 5));
m1.insert(pair<Person2, int>(p2, 3));
m1.insert(pair<Person2, int>(p3, 8));
m1.insert(pair<Person2, int>(p4, 4));
m1.insert(pair<Person2, int>(p5, 2));
for (map<Person2, int, Mycompare3>::iterator pit = m1.begin(); pit != m1.end(); pit++)
{
cout << "key(年龄):" << pit->first.m_Age << " value:" << pit->second << endl;
}
}
6.案例——员工分组
6.1案例描述:
1> 公司今天招聘了10个员工(ABCDEFGHIJ),10个员工进入公司后,需要指派员工在那个部门工作。
2> 员工信息有:姓名、工资组成;部门分为:策划、美术、研发
3> 随机给10名员工分配部门和工资
4> 通过multimap进行信息的插入,key(部门编号)、value(员工)
5> 分部门显示员工信息
6.2实现步骤
1> 创建10名员工,放在vector中
2> 遍历vector容器,取出每个员工,进行随机分组
3> 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
4> 分部门显示员工信息
5.3代码实现
class Person
{
public:
Person(string name,int wages):m_Name(name),m_Wages(wages){
}
string m_Name;
int m_Wages;
};
//创建vector存放10名员工
void CreatPerson(vector<Person> &v)
{
string nameSeed = "ABCDEFGHIJ";
int wages = rand()%10000+10000;
for(int i =0; i<10; i++)
{
string name = "员工";
name += nameSeed[i];
Person p(name,wages);
v.push_back(p);
}
}
//随机选择部门
void SelectDepartment(const vector<Person> &v, multimap<int, Person> & m)
{
int choice;
for(vector<Person>::const_iterator it = v.begin();it!=v.end();it++)
{
choice = rand()%3;
pair<int,Person> p(choice,*it);
m.insert(p);
}
}
//显示信息
void Show(const multimap<int, Person> &m)
{
//0为策划
//1为美术
//2为研发
multimap<int, Person>::const_iterator mit = m.find(0);
int count = m.count(0);
cout<<"策划部门:"<<endl;
for(int num=0;mit!=m.end()&&num<count;mit++,num++)
{
cout<<"姓名:"<<mit->second.m_Name<<" 工资:"<<mit->second.m_Wages<<endl;
}
cout<<endl;
count = m.count(1);
cout<<"美术部门:"<<endl;
for(int num=0;num<count;num++)
{
cout<<"姓名:"<<mit->second.m_Name<<" 工资:"<<mit->second.m_Wages<<endl;
}
cout<<endl;
count = m.count(2);
cout<<"技术部门:"<<endl;
for(int num=0;num<count;num++)
{
cout<<"姓名:"<<mit->second.m_Name<<" 工资:"<<mit->second.m_Wages<<endl;
}
}
void test9()
{
//创建10名员工并存储在vector中
vector<Person> v;
CreatPerson(v);
//遍历vector,随机分配部门
multimap<int, Person> m;
SelectDepartment(v,m);
//显示信息
Show(m);
}
int main()
{
srand(time(NULL));
test9();
return 0;
}