您的位置:首页 > 编程语言 > C语言/C++

C/C++ Map 关于insert、iterator、erase、char * key总结

2017-02-22 21:39 531 查看
本文主要讲解了STL map常用方法insert,及与之相关的pair、make_pair,同时简明阐述了iterator+erase结合使用时可能出现的问题。

目录:

insert

iterator erase

char - key

insert

STL中map是以
<key,value>
字典形式存储数据,一般可以使用
make_pair
构造键值对,比如:

make_pair(1,”Beixi Fish”);

其中,map中key值是唯一的,如果重复插入就会造成insert fail. 所以判断insert是否成功,就显得尤为重要!

insert主要有三种写法:

theMap.insert(pair<int,const char *>(1,"Beixi Fish"));
theMap.insert(make_pair(2,"Beixi Fish"));
theMap[3] = "Beixi Fish";


map中存储结构为pair,
make_pair
pair
最明显的区别是:使用pair时需要强制指明类型。

一般建议使用pair,网上说该性能最佳。

pair函数声明如下:

pair<map<int,const char*>::iterator, bool> a = theMap.insert(pair<int,const char *>(1,"Beixi Bear"));
//make_pair
pair<map<int,const char*>::iterator, bool> b = theMap.insert(make_pair(1,"Beixi Bear"));


根据map使用方式,或者一般迭代器的使用方法,可以有知道可以这样使用:

//pair<map<int,const char*>::iterator, bool> b;
map<int,const char*>::iterator iter = b.first;
bool ret = b.second;


而STL-map中,当insert失败时,pair第二个参数为
false
,从而有以下一段完整的insert示例:

#include <iostream>
#include <map>
using namespace std;

int main(void){
//key - value
map<int,const char*> theMap;

bool ret = theMap.insert(make_pair(1,"Beixi Fish")).second;
if (!ret){//delete
printf("insert fail. - Beixi Fish");
}

ret = theMap.insert(make_pair(1,"Beixi Bear")).second;
if (!ret){//delete
printf("insert fail. Beixi Bear");
}

return 0;
}


这里说明一下,如果你的
make_pair
的第二个参数const char*是在堆(new)上开辟的,那么你应该在if(!ret){}中delete它,以避免内存泄漏。

iterator & erase

STL map中有一个叫erase的方法:从map中删除指定的节点。

这里牵涉到一个迭代器重置的问题,试分析以下code:

#include <iostream>
#include <map>
using namespace std;

int main(void){
//key - value
map<int,const char*> theMap;

theMap.insert(make_pair(1,"Beixi Fish"));
theMap.insert(make_pair(2,"Bei Jing"));
theMap.insert(make_pair(3,"China"));

map<int,const char*>::iterator iter;

for (iter = theMap.begin(); iter != theMap.end(); ++iter){
theMap.erase(iter);
}

return 0;
}


当你run该程序时,直接弹出糟糕的
Debug Assertion Failed!




这里不做过多解释,而直接给出STL推荐的使用方式:

e.g.


for (iter = theMap.begin(); iter != theMap.end();  ){
theMap.erase(iter++);
}


当然,如果你要移除指定项,可以这样写:

for (iter = theMap.begin(); iter != theMap.end();  ){
if (iter->second == "Beixi Fish")
theMap.erase(iter++);
else
++iter;
}


char* -> key

这里需要再强调一个问题,尽量不要使用
map<char*, int>
,也就是说将
char *
作为key。

这将为你带来不少麻烦。

你以为map中存放的是以下这样的:

keyvalue
CSDN1
Github5
CNBLOGS2
其实,map中是这样的:

keyvalue
0xABC781
0xBCD565
0x89YTA2
有两个方法可以进行补救,

将char* 改为string;

自己动手写cmp函数,再按照以下方式定义map。

map<char*, int, cmp> mapName;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl