C++中map容器的说明和使用技巧
C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值。
一、map的说明
1 头文件
1 #include <map>
2 定义
1 map<string, int> my_Map; 2 或者是typedef map<string, int> MY_MAP; 3 MY_MAP my_Map;
3 插入数据
1 (1) my_Map["a"] = 1; 2 (2) my_Map.insert(map<string, int>::value_type("b",2)); 3 (3) my_Map.insert(pair<string,int>("c",3)); 4 (4) my_Map.insert(make_pair<string,int>("d",4));
4 查找数据和修改数据
1 (1) int i = my_Map["a"]; 2 my_Map["a"] = i; 3 (2) MY_MAP::iterator my_Itr; 4 my_Itr.find("b"); 5 int j = my_Itr->second; 6 my_Itr->second = j;
不过注意,键本身是不能被修改的,除非删除。
5 删除数据
1 (1) my_Map.erase(my_Itr); 2 (2) my_Map.erase("c");
还是注意,第一种情况在迭代期间是不能被删除的,道理和foreach时不能删除元素一样。
6 迭代数据
1 for (my_Itr=my_Map.begin(); my_Itr!=my_Map.end(); ++my_Itr) {}
7 其它方法
1 my_Map.size() 返回元素数目 2 my_Map.empty() 判断是否为空 3 my_Map.clear() 清空所有元素
可以直接进行赋值和比较:=, >, >=, <, <=, != 等等 。
1 int main(int argc, char* argv[])
2 {
3 map<string, string> mapData;
4
5 mapData["a"] = "aaa";
6 mapData["b"] = "bbb";
7 mapData["c"] = "ccc";
8
9
10 for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); i++)
11 {
12 if (i->first == "b")
13 {
14 mapData.erase(i);
15 }
16 }
17 return 0;
18 }
错误:
i指针在元素被删除后失效了,回到for语句中与mapData.end() 进行比较错误,这个一般都了解。
下面这个是正确删除方法:
1 int main(int argc, char* argv[])
2 {
3 map<string, string> mapData;
4
5 mapData["a"] = "aaa";
6 mapData["b"] = "bbb";
7 mapData["c"] = "ccc";
8
9
10 for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); /*i++*/)
11 {
12 if (i->first == "b")
13 {
14 mapData.erase(i++);
15 }
16 else
17 {
18 i++;
19 }
20 }
21 return 0;
22 }
这里贴出一个新的错误:
1 int main(int argc, char* argv[])
2 {
3 map<string, string> mapData;
4
5 mapData["a"] = "aaa";
6 mapData["b"] = "bbb";
7 mapData["c"] = "ccc";
8
9
10 for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); /*i++*/)
11 {
12 if (i->first == "b")
13 {
14 mapData.erase(i/*++*/);
15 }
16 else
17 {
18 /*i++*/;
19 }
20 i++;
21 }
22 return 0;
23 }
这同样是另外一个错误。i++操作主要做三件事情:
1、首先把i备份一下。
2、把i加上1。
2、返回第一步备份的i。
mapData.erase(i++);
在执行erase之前,i已经被加1了。erase会使得以前那个未被加一的i失效,而加了一之后的新的i是有效的。
mapData.erase(i); // erase以后 i已经失效,不能再用i++;
i++;
那么erase操作直接让i失效,对失效的i进行加一操作也是失效的。
mapData.erase(i++);
这段代码的真正等效代码是
map<string, string>::iterator iterTemp = i;
++i;
mapData.erase(iterTemp);