C++STL之map的基本操作

STL中基本的关联式容器有map和set,它们都是以红黑树作为其底层的结构,具有非常高的查找、删除效率,内容会按照键值自动排序。

使用map的注意事项:

1、关联式容器的键值是不允许修改的,所以永远不要试图去修改关联式容器的键值

2、插入数据时,如果使用的是insert,并且新插入的键值在原映射中已经存在,那么只是单纯的插入不成功,不会对原映射造成影响,如果使用[]进行插入操作,并且新插入的键值在原映射中已经存在,那么会将原映射中的实值改成要插入的实值。

3、insert插入操作会用到pair结构,pair结构在utility头文件中

4、查找数据时,如果使用find,并且要查找的键值不存在,那么不会对原集合造成影响,如果使用[]查找,并且要查找的值不存在,会建立一个新的实值为空,键值为要查找的元素到原映射中。

5、注意find返回值不是整数,而是一个迭代器,成功返回迭代器指向要查找的元素,失败返回的迭代器指向end

6、erase的返回值是整数,返回的是成功删除元素的个数,即成功返回1,失败返回0

7、map特有的两个操作:

    upper_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数大的元素     lower_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数小的元素

 1 #include<iostream>
 2 #include<map>
 3 #include<utility>//pair的头文件
 4 #include<string>
 5 using namespace std;
 6 int main()
 7 {
 8     //**插入数据,特别注意使用insert时,如果已经存在要插入的键值,则插入操作相当于无效,而使用[]进行插入,如果已经存在要插入的键值,
 9     //那么原来键值对应的内容将会被改写
10     //insert版本1: pair(iterator,bool) insert(const pair<key_type,value_type> &value);
11     //使用pair对进行插入,返回值是一个pair对,不过两个pair的内容不一样,要插入的pair中第一个是键值,第二个是实值,
12     //返回值中pair,第一个是一个map<key_type,value_type>的迭代器表示插入数据在容器中的位置,第二个是bool类型,插入成功返回1,否则返回0;
13     map<int,string> hash;
14     typedef pair<int,string> value;
15     typedef map<int,string>::iterator it;
16     typedef pair<it,bool> result;
17     result r1=hash.insert(map<int,string>::value_type(1,"abc"));
18     //注意由于之前存在键值3,所以这次插入是无效的
19     result r2=hash.insert(map<int,string>::value_type(1,"vvv"));
20     cout<<r1.first->first<<" "<<r1.first->second<<" "<<r1.second<<endl;
21     cout<<r2.first->first<<" "<<r2.first->second<<" "<<r2.second<<endl;
22     result r3=hash.insert(value(2,"ad"));//pair
23     cout<<r3.first->first<<" "<<r3.first->second<<" "<<r3.second<<endl;
24     //insert版本2 iterator insert(iterator pos,const pair<key_type,value_type> &value) 只返回插入元素在迭代器的位置
25     map<int,string>::iterator iter;
26     iter=hash.insert(hash.begin(),value(3,"vs"));
27     cout<<iter->first<<" "<<iter->second<<endl;
28     //注意由于之前存在键值3,所以这次插入是无效的
29     iter=hash.insert(hash.begin(),value(3,"vector"));
30     cout<<iter->first<<" "<<iter->second<<endl;
31     //insert 版本3 void insert(input_iterator start,input_iterator end)
32     //注意双迭代器组成的区间是前闭后开的就好了
33     map<int ,string> ha;
34     ha.insert(hash.begin(),hash.end());
35     iter=ha.begin();
36     for(;iter!=ha.end();iter++)
37     {
38         cout<<iter->first<<' '<<iter->second<<endl;
39     }
40 
41     //[]直接插入数据,如果要插入的键值不存在,则插入一组新的映射,放回值是实值,如果存在要插入的键值,那么原来键值对应的数据会被改掉。
42     map<string,string> map_str;
43     map_str["hohai"]="100";
44     cout<<map_str["hohai"]<<endl;
45     //注意这里插入了一个已有存在相同键值的数据,实际会将原来键值对应的实值改掉
46     map_str["hohai"]="hello";
47     cout<<map_str["hohai"]<<endl;
48 
49     
50     //查找操作
51     //[]查找,从上面的例子中已经可以看到使用[]会返回一个实值的引用,可以利用这个进行查找,但是存在弊端,如果要查找的值不存在则会生成一个
52     cout<<map_str["aaa"]<<endl;
53     //find查找返回值是迭代器,成功则返回对应的迭代器,不成功返回的是end()迭代器
54     map<string,string>::iterator it_str;
55     it_str=map_str.find("hohai");
56     if(it_str!=map_str.end())
57         cout<<it_str->second<<endl;
58     else
59         cout<<"这个键值对应的元素不存在"<<endl;
60 
61     it_str=map_str.find("hehe");
62     if(it_str!=map_str.end())
63         cout<<it_str->second<<endl;
64     else
65         cout<<"这个键值对应的元素不存在"<<endl;
66 
67     //upper_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数大的元素
68     //lower_bound查找,返回的也是一个迭代器,如果存在键值,则迭代器指向该元素,如果存在该键值,那么迭代器指向第一个键值比该参数小的元素
69     //注意map是按照红黑树的结构进行存储的,添加元素的时候是会自动调整顺序的,所以这里的第一个指的是值最接近要查找的值,且比要查值稍大或者稍小的值
70     map<int,string> map_int;
71     map_int[60]="hello";
72     map_int[30]="hi";
73     map_int[100]="how are you";
74     map<int,string>::iterator it_int;
75     it_int=map_int.upper_bound(25);
76     cout<<it_int->first<<" "<<it_int->second<<endl;
77 
78     //遍历,如果键值比较有规律可以使用[]结合循环,否则使用迭代器
79 
80 
81     //删除数据
82     //map中erase有三个版本可以删除键值指定的数据,迭代器指定的数据和迭代器指定区间的数据
83     //其中使用键值删除的版本返回值是删除的个数(0或1),其他两个版本无返回值
84     cout<<map_int.erase(20)<<endl;
85     map<int,string>::iterator it_i=map_int.begin();
86     for(;it_i!=map_int.end();it_i++)
87     {
88         cout<<it_i->first<<" "<<it_i->second<<endl;
89     }
90     cout<<map_int.erase(100)<<endl;
91     for(it_i=map_int.begin();it_i!=map_int.end();it_i++)
92     {
93         cout<<it_i->first<<" "<<it_i->second<<endl;
94     }
95     return 0;
96 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AzMark

Python 学习之正则表达式「下」

re.sub(pattern, repl, string, count, flags=0) 与 re.subn(…) repl 用来替换的字符串,strin...

7810
来自专栏marsggbo

C++学习笔记之模板篇

一、模板 不管是函数模板还是类模板,在未初始化前都是不占用内存的。 另外一般来说模板代码不能分开编译,即不能分开写成.h文件和.c文件,需要写成一个文件。 ...

22180
来自专栏大数据钻研

Java基础语法

java 基 础 语 法 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念...

29960
来自专栏用户2442861的专栏

Java基础之String中equals,声明方式,等大总结

    转载请注明出处:http://blog.csdn.net/dmk877/article/details/49420141 

9020
来自专栏章鱼的慢慢技术路

C++笔试面试题整理

封装来源于信息隐藏的设计理念,是通过特性和行为的组合来创建新数据类型让接口与具体实现相隔离。

1.3K30
来自专栏逆向技术

C语言_第二讲_规范以及常用数据类型

一丶编码规范基本数据类型 编码规范 任何程序员,都应该有良好的的编码习惯,便于以后的代码可读性和维护 常见了编码规范有 匈牙利命名法 驼峰式大小写 匈牙利命名法...

26800
来自专栏全沾开发(huā)

搞懂JavaScript中的连续赋值

搞懂JavaScript中的连续赋值 前段时间老是被一道题刷屏,一个关于连续赋值的坑。 遂留下一个笔记,以后再碰到有人问这个题,直接...

41260
来自专栏Vamei实验室

Python基础02 基本数据类型

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 简单的数据类型以及赋值 变量不需要声明 P...

19850
来自专栏IT可乐

深入理解计算机系统(3.8)------数组分配和访问

  上一篇博客我们讲解了汇编语言中过程(函数)的调用实现。理解数据如何在调用者和被调用者之间传递,以及在被调用者当中局部变量内存的分配以及释放是最重要的。那么这...

224100
来自专栏WD学习记录

数据结构与算法2016-06-03

一个算法调用自己来完成它的部分工作,在解决某些问题时,一个算法需要调用自身。如果一个算法直接调用自己或间接调用自己,就称这个算法是递归的。根据调用方式的不同,它...

8520

扫码关注云+社区

领取腾讯云代金券