STL--map/multimap(5)
1.简介
- map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对。它提供基于key的快速检索能力。
- map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
- map的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比vector快。
- map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。
- multimap与map的区别:map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。
使用前的准备:
#include <map> using namespace std;
2.操作
map/multimap对象的默认构造
- map<T1,T2> mapTT;
- multimap<T1,T2> multimapTT;
如:
map<int, char> mapA;
map<string,float> mapB;
//其中T1,T2还可以用各种指针类型或自定义类型
map的插入与迭代器
- map.insert(...); //往容器插入元素,返回pair<iterator,bool>
在map中插入元素的四种方式:
1 #include <string> 2 #include <map> 3 4 using namespace std; 5 6 //main函数 7 void main() 8 { 9 map<int, string> mapA; 10 11 //插入方式一.pairResult: ((3, "小张"), true) 12 pair<map<int, string>::iterator, bool> pairResult = mapA.insert(pair<int, string>(3, "小张")); 13 14 //插入方式二 15 mapA.insert(map<int, string>::value_type(1, "小李")); 16 17 //插入方式三 18 mapA.insert(make_pair(7, "小胡")); 19 20 //插入方式四 21 mapA[5] = "小王"; 22 mapA[3] = "小刘"; //修改value 23 }
第四种方法非常直观,但存在一个性能的问题。插入3时,先在mapStu中查找主键为3的项,若没发现,则将一个键为3,值为初始化值的对组插入到mapStu中,然后再将值修改成“小刘”。若发现已存在3这个键,则修改这个键对应的value。如:
string strName = mapStu[2]; //取操作或插入操作
只有当mapStu存在2这个键时才是正确的取操作,否则会自动插入一个实例,键为2,值为初始化值。
- map<T1,T2,less<T1> > mapA; //该容器是按键的升序方式排列元素。未指定函数对象,默认采用less<T1>函数对象。
- map<T1,T2,greater<T1>> mapB; //该容器是按键的降序方式排列元素。
- less<T1>与greater<T1> 可以替换成其它的函数对象functor。
可编写自定义函数对象以进行自定义类型的比较,使用方法与set构造时所用的函数对象一样。
- map.begin(); //返回容器中第一个数据的迭代器。
- map.end(); //返回容器中最后一个数据之后的迭代器。
- map.rbegin(); //返回容器中倒数第一个元素的迭代器。
- map.rend(); //返回容器中倒数最后一个元素的后面的迭代器。
map对象的拷贝构造与赋值
- map(const map &mp); //拷贝构造函数
- map& operator=(const map &mp); //重载等号操作符
- map.swap(mp); //交换两个集合容器
map的大小
- map.size(); //返回容器中元素的数目
- map.empty();//判断容器是否为空
map的删除
- map.clear(); //删除所有元素
- map.erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
- map.erase(beg,end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
- map.erase(keyElem); //删除容器中key为keyElem的对组。
map的查找
- map.find(key); 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();
- map.count(keyElem); //返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
- map.lower_bound(keyElem); //返回第一个key>=keyElem元素的迭代器。
- map.upper_bound(keyElem); // 返回第一个key>keyElem元素的迭代器。
- map.equal_range(keyElem); //返回容器中key与keyElem相等的上下限的两个迭代器(以上函数返回两个迭代器,而这两个迭代器被封装在pair中)。上限是闭区间,下限是开区间,如[beg,end)。
1 #include <string> 2 #include <map> 3 4 using namespace std; 5 6 //main函数 7 void main()| 8 { 9 map<int, string> mapA; 10 mapA.insert(pair<int,string>(3,"小张")); 11 mapA.insert(pair<int,string>(1,"小杨")); 12 mapA.insert(pair<int,string>(7,"小赵")); 13 mapA.insert(pair<int,string>(5,"小王")); 14 15 //find方法 16 map<int, string>::iterator it1 = mapA.find(5); //it1指向{5,"小王"}元素 17 18 int iCount = mapA.count(5); //iCount == 1 19 20 //lower_bound方法 21 map<int, string>::iterator it2 = mapA.lower_bound(5); //it2指向{5,"小王"}元素 22 23 //upper_bound方法 24 map<int, string>::iterator it3 = mapA.upper_bound(5); //it3指向{7,"小赵"}元素 25 26 //equal_range方法 27 pair< map<int,string>::iterator, map<int,string>::iterator > pr = mapA.equal_range(5); 28 29 map<int, string>::iterator it4 = pr.first; //it4指向{5,"小王"}元素 30 map<int, string>::iterator it5 = pr.second; //it5指向{7,"小赵"}元素 31 32 }
3.multiset
例子:
1 #include <string> 2 #include <map> 3 #include <iostream> 4 5 using namespace std; 6 7 struct userdevice{ 8 string m_devicename; 9 long m_deviceid; 10 int m_devicePopedom; 11 }; 12 13 typedef multimap<string,userdevice> USERTABLE; 14 typedef USERTABLE::const_iterator CIT; 15 typedef pair<CIT, CIT> Range; 16 17 18 //main函数 19 void main() 20 { 21 CIT it; 22 userdevice d1,d2,d3,d4; 23 d1.m_deviceid = 12341234; 24 d1.m_devicename = "d1"; 25 d1.m_devicePopedom = 123; 26 27 d2.m_deviceid = 23622344; 28 d2.m_devicename = "d2"; 29 d2.m_devicePopedom = 234; 30 31 32 d3.m_deviceid = 3451234; 33 d3.m_devicename = "d3"; 34 d3.m_devicePopedom = 345; 35 36 d4.m_deviceid = 43622344; 37 d4.m_devicename = "d4"; 38 d4.m_devicePopedom = 456; 39 40 USERTABLE m_user; 41 m_user.insert(make_pair("zhangsanfeng",d1)); 42 m_user.insert(make_pair("zhangsanfeng",d2)); 43 44 m_user.insert(make_pair("zhangsanfeng2",d3)); 45 m_user.insert(make_pair("zhangsanfeng2",d4)); 46 //查找方法一 47 Range range=m_user.equal_range("zhangsanfeng"); 48 for(CIT i = range.first;i!=range.second;i++) 49 { 50 cout << i->second.m_deviceid<<',' 51 << i->second.m_devicename.c_str()<<',' 52 <<i->second.m_devicePopedom 53 << endl; 54 } 55 cout<<endl; 56 //查找方法二 57 CIT it2 = m_user.find("zhangsanfeng2"); 58 while(it2 != m_user.end()) 59 { 60 cout<<it2->second.m_deviceid<<',' 61 <<it2->second.m_devicename.c_str()<<',' 62 <<it2->second.m_devicePopedom<<',' 63 <<endl; 64 it2++; 65 } 66 cout<<endl; 67 //遍历 68 CIT it3 = m_user.begin(); 69 while(it3 != m_user.end()) 70 { 71 cout<<it3->second.m_deviceid<<',' 72 <<it3->second.m_devicename.c_str()<<',' 73 <<it3->second.m_devicePopedom<<',' 74 <<endl; 75 it3++; 76 } 77 78 }