STL之关联容器

 关联容器支持高效的关键字查找和访问。两个主要的关联容器(associative-container)类型是map和set。标准库提供8个关联容器,它们的不同体现在三个维度上:

  • 或者是一个set,或者是一个map
  • 或者要求不重复的关键字,或者允许重复关键字
  • 按顺序保存元素,或无序保存。

允许重复关键字的容器的开头名字中都包含单词multi;不保持关键字按顺序存储的容器的名字都以单词unordered开头。

类型mapmultimap定义在头文件map中;setmultiset定义在头文件set中,无序容器则定义在unordered_mapunordered_set中。

关联容器概述

定义关联容器

每个关联容器都定义了一个默认构造函数,它创建一个指定类型的空容器。也可以将关联容器初始化为另一个同类型容器的拷贝,或是从一个值范围来初始化关联容器,只要这些值可以转化为容器所需类型就可以。在新标准下,也可以对关联容器进行值初始化。

map<string, size_t> word_count; //空容器
set<string> exclude = {"the", "but", "and", "or"}; //列表初始化
//三个元素:authors将姓映射为名
map<string, string> authors = {
    {"Joyce", "James"},
    {"Austen", "Jane"},
    {"Dickens", "Charles"}
};

初始化一个map时,必须提供关键字和值类型。我们将每个关键字-值对包围在花括号中: {key,value} 

来指出它们一起构成了map中的一个元素。

初始化multimap和multiset

一个map或set中的关键字必须是唯一的,multimap和multiset则没有此限制。

vector<int> ivec;
for(vector<int>::size_type i = 0; i != 10; i++)
{
    ivec.push_back(i);
    ivec.push_back(i);
}

set<int> iset(ivec.begin(), ivec.end());
multiset<int> miset(ivec.begin(), ivec.end());

cout<<ivec.size()<<endl; //打印出20
cout<<iset.size()<<endl; //打印出10
cout<<miset.size()<<endl; //打印出20

pair类型

定义在头文件utility中。
一个pair保存两个数据称愿。类似容器,pair是一个用来生成特定类型的模板。当创建一个pair时,我们必须提供两个类型名,pair 的数据成员将具有对应的类型。两个类型不要求一样。

pair<string, string> anon;
pair<string, size_t> word_count;
pair<string, vector<int>> line;

pair的默认构造函数对函数成员进行值初始化(string被初始化为空字符串,size_t被初始化为0)。也可以为每个成员提供初始化器:

pair<string, string> author("James", "Joyce");
pair<string, string> author()

与其他标准库类型不同,pair的数据成员是public的,两个成员分别命名为first和second,我们用普通的成员访问符号来访问它们。

其他操作:

pair<string, string> author;
pair<string, string> author1("aaaa","dddd");
pair<string, string> author2{"aaaa","dddd"};
pair<string, string> author3 = {"aaaa","dddd"};

//返回一个用v1和v2初始化的pair,pair的类型从v1和v2的类型推断出来
auto p = make_pair(11,22);
auto q = make_pair("aaaa", "bbbb");

关联容器操作

类型别名 含义
key_type 此容器类型的关键字类型
mapped_type 每个关键字关联的类型;只适用于map
value_type 对于set,与key_type相同
对于map,为pari<const key_type, mapped_type>

由于我们不能改变一个元素的关键字,因此这些pair的关键字部分是const的。只有map类型才定义了mapped_type。

一个map的value_type是一个pair,我们可以改变pair的值,但不能改变关键字成员的值。

添加元素

c.insert(v) //v是value_type类型的对象
c.emplace(args)
c.insert(b,e) //b,e是迭代器
c.insert(il) //il是value_type类型值的花括号列表
c.insert(p, v) //类似于`insert(v)`,但将迭代器p作为一个提示,指出从哪里开始搜索新元素应该存储的位置
c.emplace(p, args)

删除元素

c.erase(k) //从c中删除每个关键字为k的元素,返回一个size_t类型的值,指出删除的元素的数量
c.erase(p) //从c中删除迭代器p指定的元素,返回一个指向p之后元素的迭代器
c.erase(b, e) 删除迭代器对b和e所表示的范围中的元素。返回e。

map的下标操作

类似于其他下标操作符,map下标操作符接受一个索引,获取与此关键字相关联的值。与其他下标操作不同的是,如果关键字不存在于map中,会为它创建一个元素并插入到map中,关联值将进行值初始化。

操作 含义
c[k] 返回关键字为k的元素;如果不存在则添加一个关键字为k的元素,对其进行值初始化
c.at(k) 访问关键字为k的元素,带参数检查;若k不在c中,抛出一个out_of_range异常

map的下标操作符返回一个左值,既可以读也可以写。

访问元素

操作 含义
c.find(k) 返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器
c.count(k) 返回关键字等于k的元素的数量。对于不允许重复的容器,返回值永远是0或1
c.lower_bound(k) 返回一个迭代器,指向第一个关键字不小于k的元素
c.upper_bound(k) 返回一个迭代器,指向第一个关键字大于k的元素
c.equal_range(k) 返回一个迭代器pair,表示关键字等于k的元素的范围。若k不存在,pair的两个成员均等于c.end()

无序容器

新标准定义了4个无序关联容器(unordered associative container)。这些容器不是使用比较运算符来组织元素,而是使用一个哈希函数(hash function)和关键字类型的==运算符。

除了哈希管理操作之外,无序容器还提供了与有序容器相同的操作。

有序容器的迭代器通过关键字有序访问容器中的元素。无论在有序容器中还是在无序容器中,具有相同关键字的元素都是相邻存储的。

哈希函数(hash function)将给定类型的值映射到整型(size_t)值的函数。相等的值必须映射到相同的整数;不相等的值应尽可能映射到不同整数。

严格弱序:关联容器所使用的关键字间的关系。在一个严格弱序中,可以比较任意两个值并确定哪个更小。若任何一个都不小于另一个,则认为这两个值相等。

转载:http://blog.csdn.net/foreverling/article/details/44274699

时间: 2024-10-30 05:15:33

STL之关联容器的相关文章

Effective STL 为包含指针的关联容器指定比较类型

// 为包含指针的关联容器指定比较类型.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <set> #include <string> #include <iostream> using namespace std; struct StringPtrLess: public binary_function<const string*, const string*, bool> {

C++程序设计:原理与实践(进阶篇)16.6 关联容器

16.6 关联容器 除了vector之外,最有用的标准库容器恐怕就是map了.一个map就是一个(键,值)对的有序序列,你可以基于一个关键字在其中查找对应的值:例如my_phone_book["Nicholas"]应该是Nicholas的电话号码.在流行度的竞争中,map唯一的潜在竞争对手是unordered_map(见16.6.4节),它是一种针对字符串关键字优化过的map.类似map和unordered_map的数据结构有很多名字,例如关联数组(associative array)

关于STL中set容器的一些总结_C 语言

1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作.vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入.排序.删除.查找等.让用户在STL使用过程中,并不会感到陌生. 关于set,必须说明的是set关联式容器.set作为一个容器也是

使用 &amp;lt;multimap&amp;gt; 库创建重复键关联容器

摘要:标准库的 multimap 容器与 map 关联容器非常类似--但是, multimap 允许重复键.这个特性使得 multimap 比想象的要有用得多.本文将对之进行探讨 . 在"使用 <map> 库创建关联容器"一文中,我们讨论了标准库 中的 map 关联容器.但那只是 map 容器的一部分.标准库还定义了一个 multimap 容器, 它与 map 类似,所不同的是它允许重复键.这个属性使得 multimap 比预想的要更有用:比 如在电话簿中相同的人可以有两个

使用 &amp;lt;map&amp;gt; 库创建关联容器

摘要:当索引是整型,那么将值与之关联并不难,但如果数据的关联值对是其它数据类型怎么办呢?<map>库具备一个关联容器,使用它可以很方便地关联所有类型的数据对.本文将讨论 <map> 库的使用方法和技巧. 关系数据库,科学计算应用以及基于Web的系统常常需要类似 vector 的容器,其索引可以是如何数据类型,不一定是整数.这样的容器叫关联容器,或者 map.例如,目录服务应用可以将私人姓名作为索引来存储,电话号码作为其关联的值: directory["Harry"

c++关于关联容器的迭代器问题

问题描述 c++关于关联容器的迭代器问题 在multimap这种容器中,一个键对应多个值,如果我用迭代器iter指向初始值,则iter->first指向键,那么iter->second指向什么,因为是一键多值,怎样用迭代器遍历这个键的所有的值又如何遍历这个容器的所有的键和值 解决方案 http://www.kuqin.com/cpluspluslib/20071231/3265.html 解决方案二: iter->second指向这个key对应的所有值的一个集合,它的每个元素你又可以用一

[C++ 面试基础知识总结] 关联容器

[C++ 面试基础知识总结] 关联容器 参考书籍:<C++ Primer> 目录 C 面试基础知识总结 关联容器 目录 关联容器类型 关联容器概述 定义关联容器 关键字类型的要求 pair 关联容器操作 关联容器迭代器 添加元素 删除元素 访问元素 无序容器 关联容器类型 标准库共提供了8个关联容器 map 关联数组:保存关键字-值对 set 关键字即值,即只保存关键字的容器 multimap 关键字可重复出现的map multiset 关键字可重复出现的set unordered_map 用

c++-关联容器初始话化,如下:

问题描述 关联容器初始话化,如下: 我用multiset miset(ivec.cbegin(), ivec.cend())初始化,等到我输出cout << miset.size() << endl;为什么显示0:ivec已经初始化,初始化的程序是: for(vector::size_type i = 0; i != 10; ++i) { ivec.push_back(i); ivec.push_back(i); //每个数重复保存一次 } 解决方案 先看ivec的size是多少

C++中 set,multiset,map,multimap 关联容器实例教程

测试环境:windows 7 vs2010 内部元素有序排列,新元素插入的位置取决于它的值,查找速度快. 除了各容器都有的函数外,还支持以下成员函数: find: 查找等于某个值的元素(x小于y和y小于x同时不成立即为相等)lower_bound: 查找某个下界upper_bound: 查找某个上界equal_range: 同时查找上界和下界count:计算等于某个值的元素个数(x小于y和y小于x同时不成立即为相等)insert: 用以插入一个元素或一个区间 在学习关联容器之前,我们先要学习pa