走近STL - map,只愿一键对一值
【摘要】 系列目录:走近STL - STL概论
文章目录
1、map的特性2、map结构设计map的迭代器 3、与map相关的方法
1、map的特性
map,与前面几章讲的Vector、List不同,map属于关联容器。 map可真称得上是代码界“好男人”了,为啥呢? 这还要从map的几个特性说起:
map所有元素都是pair,同时拥有实值(v...
系列目录:走近STL - STL概论
1、map的特性
map,与前面几章讲的Vector、List不同,map属于关联容器。
map可真称得上是代码界“好男人”了,为啥呢?
这还要从map的几个特性说起:
- map所有元素都是pair,同时拥有实值(value)和键值(key).
- pair的第一元素被视为键值,第二元素被视为实值
- map中所有键值都不能重复
- map每个键值只对应一个实值
称之为:唯愿一键对一值啊。
看一下源码中关于pair的定义吧:
template <typename T1,typename T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()),second(T2()){}
pair(const T1 &a,const T2 &b) : first(a),second(b){}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2、map结构设计
SGI STL map是以红黑树为底层模型(红黑树在后面的章节会讲),几乎所有的map行为,都只是调用了红黑树的操作行为而已。
map的迭代器
这个还是比较关心的东西,如果看了前面几篇的话。
我们不能通过迭代器修改map的键值,因为键值关系到map的排列规则;但是如果要修改实值那是可以的。
map的迭代器和list的迭代器有一定的相似之处,当客户端对map使用增删操作之后,迭代器仍然是有效的,那个被删除节点的迭代器是个例外。
3、与map相关的方法
还是选取最朴实无华的,但确是最实用的并经过亲测的方法,兼容VC98版本编译器。
- 初始化
#include <iostream>
#include <map>
using namespace std;
map<string,int> maptest; //以string为键值,以int为实值
- 1
- 2
- 3
- 4
- 5
- 6
- 增
//插入方法多种多样,这里提几个基本的,万变不离其中
maptest.insert(pair<string, int>('a', 100)); //单值插入
map<char, int>::iterator it = maptest.begin();
maptest.insert(it,pair<char, int>('b', 200)); //指定位置插入
//其实我个人是不知道这种插入方式有什么意义,反正你插进去人家就给你排序了,插哪儿都得被安排
map<char, int> anothermap;
anothermap.insert(maptest.begin(), maptest.find('c')); //map内容复制
//这个c自己去插
//这个复制严格体现了STL左开右闭的原则,键值为c的那个键值对不会被复制过去
//如果要全部复制,右边放一个不存在的键值就好
anothermap.insert({ { 'd', 100 }, {'e', 200} }); //列表形式插入
//这个简单是吧,一步到位。
//不过不好意思,这个是VC11才开始支持的哦
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
新增元素还有几个小问题,如何判断是否插入成功?如果对一键值重复插入又会如何?如果只插入键不插入值会怎样呢?···
//首先,是不允许只插入一半的。
//然后,如果重复插入,则第一次之后的插入都会返回插入失败。
//那么如何判断插入成功?
- 1
- 2
- 3
- 4
//格式如下:
pair<map<string, int>::iterator, bool> ret;
ret = maptest.insert(std::pair<string, int>('a', 500));
if (ret.second == false)
{ cout << "element 'a' already existed"; cout << " with a value of " << ret.first->second << '\n';
}
//对于想快速上手的朋友,直接套模板就好
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 删
删除方法也多样,我就举几个常用的:
maptest.erase('a'); //通过键值删除,如果指定了无效的键值,将不会执行删除命令
map<char, int>::iterator it = maptest.begin();
maptest.erase(it); //通过迭代器删除,有任何问题可以参见前面提到的迭代器
maptest.erase(maptest.begin(),maptest.end()); //成片删除,很遗憾,这个不遵循左开右闭原则,全删了1
- 1
- 2
- 3
- 4
- 5
- 6
- 查
// 关键字查询,找到则返回指向该关键字的迭代器,否则返回指向end的迭代器
// 根据map的类型,返回的迭代器为 iterator 或者 const_iterator
iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
anothermap.insert(maptest.begin(), maptest.find('c')); //像这样
- 1
- 2
- 3
- 4
- 5
- 6
其他内容查询:
// 查询map是否为空
bool empty();
// 查询map中键值对的数量
size_t size();
// 查询map所能包含的最大键值对数量,和系统和应用库有关。
// 此外,这并不意味着用户一定可以存这么多,很可能还没达到就已经开辟内存失败了
size_t max_size();
// 查询关键字为key的元素的个数,在map里结果非0即1
size_t count( const Key& key ) const; //
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
本篇仅用于map快速上手学习,针对性比较强。如果想深入学习,可以关注我的STL专栏,之后会有对STL-map的源码剖析文章。
文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。
原文链接:lion-wu.blog.csdn.net/article/details/105439030
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)