走近STL - map,只愿一键对一值

时间:2022-07-23
本文章向大家介绍走近STL - map,只愿一键对一值,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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){}
}

2、map结构设计

SGI STL map是以红黑树为底层模型(红黑树在后面的章节会讲),几乎所有的map行为,都只是调用了红黑树的操作行为而已。

map的迭代器

这个还是比较关心的东西,如果看了前面几篇的话。 我们不能通过迭代器修改map的键值,因为键值关系到map的排列规则;但是如果要修改实值那是可以的。 map的迭代器和list的迭代器有一定的相似之处,当客户端对map使用增删操作之后,迭代器仍然是有效的,那个被删除节点的迭代器是个例外。

3、与map相关的方法

还是选取最朴实无华的,但确是最实用的并经过亲测的方法,兼容VC98版本编译器。

  1. 初始化
#include <iostream>
#include <map>

using namespace std;

map<string,int> maptest;	//以string为键值,以int为实值
//插入方法多种多样,这里提几个基本的,万变不离其中

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才开始支持的哦

新增元素还有几个小问题,如何判断是否插入成功?如果对一键值重复插入又会如何?如果只插入键不插入值会怎样呢?···

//首先,是不允许只插入一半的。
//然后,如果重复插入,则第一次之后的插入都会返回插入失败。

//那么如何判断插入成功?
//格式如下:
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. 删 删除方法也多样,我就举几个常用的:
maptest.erase('a');	//通过键值删除,如果指定了无效的键值,将不会执行删除命令

map<char, int>::iterator it = maptest.begin();
maptest.erase(it);	//通过迭代器删除,有任何问题可以参见前面提到的迭代器

maptest.erase(maptest.begin(),maptest.end());	//成片删除,很遗憾,这个不遵循左开右闭原则,全删了1
// 关键字查询,找到则返回指向该关键字的迭代器,否则返回指向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'));	//像这样

其他内容查询:

// 查询map是否为空
bool empty();

// 查询map中键值对的数量
size_t size();

// 查询map所能包含的最大键值对数量,和系统和应用库有关。
// 此外,这并不意味着用户一定可以存这么多,很可能还没达到就已经开辟内存失败了
size_t max_size();

// 查询关键字为key的元素的个数,在map里结果非0即1
size_t count( const Key& key ) const; //

本篇仅用于map快速上手学习,针对性比较强。如果想深入学习,可以关注我的STL专栏,之后会有对STL-map的源码剖析文章。