STL中的Set和Map——入门新手篇
STL中的Set和Map
先来看一段网络上的文字描述:
上图是一段关于STL中Set集合的描述,同样的,也近似适合Map的描述。上述文字中,描述了最为重要的特征:
Set和Map,底层调用了红黑树的结构,并且实现的是一种自动平衡二叉搜索树。
- Set
平衡二叉搜索树(Set)
如上图,STL中Set实现的本质是),insert(5),则只会执行第一次的insert操作。后续的插入,并不会执行,因为Set结构的树中无重复元素。
另一个点在于,Set中被插入的键不能被修改,也就是通过迭代器修改键值是不被允许的。因为键值一旦被修改,就意味着树的结构遭到了破坏,而这在最坏的情况意味着:整棵二叉树遭到了破坏,甚至需要重构整棵二叉树。即使在红黑树中,并没有这样的操作。因为红黑树的最为显著的特征为:局部调整。即对于Set而言,其iterator属于const-iterator。
另外一个需要被注意的点在于:
我们使用迭代器来访问容器是一件很平常的事情,上述代码是一段使用极其平常的代码,其作用是遍历Set中所有的元素。注意循环的终止条件是:!=,而不是:<。我们通常习惯了小于的小法:
即:
但这样的写法是错误的。
上述讲述了set的插入和遍历的过程,下面补充一点关于查找的知识点:
set<int>::iterator ite; ite = set1.find(); if(ite != set1.end()) { cout<<"5 found"<<endl; } ite = set1.find(); if(ite == set1.end()) { cout<<"1 not found"<<endl; } cout<<endl;
可以,如果想查找某一个元素在set中是否存在,使用容器的方法find来查找key,方法find返回的是迭代器,如果找到(即存在这个键),则迭代器不等于set.end(),否则的话,没找到,返回的迭代器等于set.end()。
- Map
下面来看Map,Map的结构形成机理和Set几乎是一模一样的,而Map的结构如下:
"挂件"平衡二叉搜索树(Map)
Map的结构如上图:可见,同Set相比,Map只是多了一个"挂件",也就是常说的Map是由:键—值对构成的。键充当了索引,值则记录了一些其他内容。而对于Set而言,只有键。或许我们用下面这个表来描述更为合适:
键—值对
索引序号 |
名字 |
1 |
张三 |
2 |
李四 |
3 |
王五 |
左边的索引号就是键,右边的名字就是值,所以说Map实际上是一种极为普遍简单的概念。这种关系就像字典一样。
而关于Map的其他性质,和Set是极其类似的。比如:没有相同的元素,当然对于Map而言,没有相同的元素是只没有两个元素键相同。执行两个insert,仍然会只有一对键值对存在树中,且第二次执行insert不会修改第一次的值,如下图:
上述代码执行的结果:key=1的节点的value="master",而非是value="docter";可见,执行两次insert,并不会修改同一个key所对应的value.但这并不意味着,Map中的值不能修改。在下面我们将认识到这一点。
在上述代码中,我们使用了类似于数组的索引方式,试图对key=1的节点进行修改,最终将key=1节点的value值修改为了"dcoter"。下面,我们来看看,通过迭代器的索引方式能否修改value,
上述中,我们使用了迭代器的索引方式,结果节点key=1的value值也被修改为了"docter"。由此可见,调用insert方法并不能修改key所对应的value值。另外,我们仍然要给出在Map中,如何的访问键和值的做法:
可见,在Map中访问key的方式为:iterator->first;访问value的方式为iterator->second。
同样的,"的"王五"修改为"赵六";但我们不能将索引号3修改为4,(我们只能将3删除,再添加4,这是可以的)。当然是用迭代器访问时,其也只能用!=,而不是<。
我们再来看看,关于Map一个很有意思的事情:
上图中,想表明两个点:
第一:有一行代码为:score["zhao liu"] = 93.5;可见,对于map而言,我们可以使用类似数组的索引方式,但是数组的索引只能是无符号整型索引,但是对于Map而言,则要广泛的多。可以是任意定义了的key的类型。
第二:我们看一下上述代码的运行结果:
前述内容表明:当索引key为整型的时候,Map的输出结果为按key升序输出。很明显,对于key为string类型而言,同样按照ASCII码的升序输出。
关于map的查找和set是类似的,并无什么高明的手段:
map<string,double>::iterator ite_x; ite_x = score.find("zhang san"); if(ite_x != score.end()) { cout<<"zhang san found"<<endl; } cout<<endl;
如上图,仍然是通过迭代器的find方法进行查找。需要注意的是:我们在进行查找的时候,查找的一定是键,而不是值,这在set和map中是保持一致的。
而关于map,还有一点关于左值运用和右值运用的知识,如下图:
score["zhao liu"] = 93.5; double zhao_score = score["zhao liu"]; cout <<"zhao's score:"<<zhao_score<<endl; zhao_score = ; cout <<"zhao's score:"<<score["zhao liu"]<<endl; cout<<endl;
第一行代码是个左值引用,第二行代码为右值引用,即使zhao_score为引用,但是改变zhao_score的值,并不会改变score["zhao liu"]的值。
STL中的Set和Map——入门新手篇的更多相关文章
- C++ STL中哈希表Map 与 hash_map 介绍
0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...
- stl中顺序性容器,关联容器两者粗略解释
什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...
- C++ STL中Map的按Key排序和按Value排序
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...
- STL中map与hash_map的比较
1. map : C++的STL中map是使用树来做查找算法; 时间复杂度:O(log2N) 2. hash_map : 使用hash表来排列配对,hash表是使用关键字来计算表位置; 时间复杂度:O ...
- STL中map与hash_map容器的选择收藏
这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自al ...
- C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET
C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...
- STL中map用法
Map是 STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于 这个特性,它完成有可能在我们处理一对一数据的 ...
- C++STL中map容器的说明和使用技巧(杂谈)
1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自 ...
- STL中关于map和set的四个问题?
STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: 为何map和set的插入删除效率比用其他序列容器高? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. ...
随机推荐
- SpringBoot2.x整合JDBC及初始化data.sql和schema.sql脚本
今天在使用SpringBoot2.x版本整合JDBC时遇到了一些问题:由于我之前一直用SpringBoot1.5的版本,所以直接在yml里按照1.5的版本配置了属性,没想到2.x直接不能用了.首先是数 ...
- Mavn 项目 引入第三方jar包 导致ClassNotFoundException
案例 我有一个Maven构建的项目,项目模块之间有依赖关系,我需要用到一个本地的jar包,而该jar包不能通过配置pom.xml文件从远程仓库自动下载,于是我直接导入该jar包到其中一个项目,不通过p ...
- 微服务之docker(二)
一.SpringCloud/SpringBoot整合docker 使用docker的maven组建构建springboot应用(官方文档:https://spring.io/guides/gs/spr ...
- SpringBoot学习笔记 文件访问映射
通过SpringBoot可以把磁盘内所有的文件都访问到 有一张图片存放在 E://images/acti/123.jpg import org.springframework.context.anno ...
- Go语言实现:【剑指offer】构建乘积数组
该题目来源于牛客网<剑指offer>专题. 给定一个数组A[0,1,-,n-1],请构建一个数组B[0,1,-,n-1],其中B中的元素B[i]=A[0] * A[1] * - * A[i ...
- 2020牛客寒假算法基础集训营4 D:子段异或
D : 子段异或 考察点 : 位运算,前缀和,异或的性质和应用 坑点 : 0 - L 的异或值是 0 的话也是一个区间 相同的值可能有多个,那么这时候区间就会有多个(x * (x + 1) / 2) ...
- 高精度模板(Vector实现更加方便)
计算的数long long 甚至更大的数据类型的都存不下的时候,应该怎么办 ? 解决方法 :我们可以把一个很大的数当做字符串进行处理,这时候就需要用到高精度. 话不多说,咱们边看代码边处理 : 加法 ...
- pytorch-- Attention Mechanism
1. paper: Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translat ...
- ELF文件之一——
ELF文件整体布局 下图是后来例子中main.o和main.elf的布局. 其中,只有elf header的位置是固定的,固定在文件开始,其它部分的位置都不确定. 比如下面的main.o布局中,.te ...
- [Linux]curl 获取本服务器公网IP
curl ifconfig.me curl icanhazip.com curl curlmyip.com curl ip.appspot.com curl ipinfo.io/ip curl ipe ...