前言
这一章介绍了关联容器,对于关联容器可以认为是下标为关键字的数组,关联容器不支持随机访问。只能使用关键字作为索引来进行访问值。关于更多的知识,大家可以自行查看书籍,这里主要介绍一些细节问题。
最后,如果有理解不对的地方,希望大家不吝赐教,谢谢!
八、关联容器
关联容器中的元素是按关键字来保存和访问的。两个主要的关联容器类型是map和set。map中的元素是一些关键字——值(key-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字:set支持高效的关键字查询操作——检查一个给定关键字是否在set中。
使用关联容器
map类型通常被称为关联数组,关联数组与“正常”数组类似,不同之处在于其下标不必是整数。与之相对,set就是关键字的简单集合,当只想知道一个值是否存在时,set是最有用的。
使用map
对于map<int,int> m;前一个代表下标类型,后一个代表值类型,对于使用第一个数据,可以采用m.first,对于使用第二个数据,可以采用m.second。
使用set
set也是一个模板,必须指定类型,与顺序容器不同的是:可以说set是集合,每一个关键字不一样,而顺序容器里的是内容,允许有一样的。
pair类型
定义在头文件utility中。一个pair保存两个数据成员,类似容器,pair是一个用来生成特定类型的模板。当创建一个pair时,我们必须提供两个类型名。例如:pair<string,string> pir;我们也可以用pir.first来使用第一个元素,用pir.second来使用第二个元素。
关联容器迭代器
当解引用一个关联容器迭代器时,我们会得到一个类型为容器的value_type的值的引用。对于map而言,value_type是一个pair类型,其first成员保存const关键字,second成员保存值。
必须记住:一个map的value_type是一个pair,我们可以改变pair的值,但不能改变关键字成员的值,即可以改变second的值,不能改变first的值,因为关键字是const的。
set的迭代器是const的
遍历关联容器
map和set类型都支持begin和end操作,可以用这些函数获取迭代器,然后用迭代器遍历容器。
添加元素
向一个map添加元素
对一个map进行insert操作时,必须记住元素类型是pair。
//向word_count插入word的4种方法 word_count.insert({word,1}); word_count.insert(make_pair(word,1)); word_count.insert(pair<string,size_t>(word,1)); word_count.insert(map<string,size_t>::value_type(word,1));
对于不包含重复关键字的容器,添加单一元素的insert和emplace版本返回一个pair,告诉我们操作是否成功。pair的first成员是一个迭代器,指向具有给定关键字的元素;second成员是一个bool值,指出元素是插入成功还是已经存在于容器中。
删除元素
通过传递给erase一个迭代器或一个迭代器对来删除一个元素或者一个元素范围。指定的元素被删除,函数返回void。还可以接受一个key_type参数,此版本删除给定关键字的元素,返回实际删除的元素的数量。
map的下标操作
map下标运算接受一个索引,获取与此关键字相关联的值。但是,与其他下标运算符不同的是,如果关键字并不在map中,会为它创建一个元素并插入到map中,关联值将进行值初始化。
访问元素
对于不允许重复关键字的容器,可能使用find还是count没什么区别,但对于允许重复关键字的容器,count还会做更多的工作:如果元素在容器中,它还会统计有多少个元素有相同的关键字,如果不计数,最好使用find。返回一个迭代器,如果没找到,则返回尾迭代器。
无序容器
定义了4个无序关联容器,这些容器不是使用比较运算符来组织元素,而是使用一个哈希函数和关键字类型的==运算符。在关键字类型的元素没有明显的序关系的情况下,无序容器是非常有用的。hash特殊的标准库模板,无序容器用它来管理元素的位置。