点击查看Evernote原文。

#@author:       gr
#@date: 2014-08-23
#@email: forgerui@gmail.com

STL中的关联容器。

###stl学习

 |--迭代器

 |--类属算法

 |--容器

   |--vector

   |--deque

   |--list

   |--set

   |--map

 |--函数对象

 |--适配器

 |--分配器

一、Contents

1. why关联容器

序列容器以线性排列方式保存数据项,并且各数据项保持了它们在插入时的相对位置,关联容器则摒弃了这种顺序,把注意力集中在如何通过保存在数据中的索引项来尽可能快地检索到数据项。

2. 实现形式

一种方法可以把索引项按照某种全序关系排列起来,用二叉树查找,时间复杂度为O(log N)。

一种方法是使用散列函数,时间复杂度为常数。

3. 四种关联容器

set和multiset,其数据项就是索引项本身,其区别是multiset允许出现重复索引项。

map和multimap,数据项是由索引项和其他的数据类型组成的一对数据,同样,区别就是multimap允许出现重复索引项。

4. set && multiset

template <typename Key, typename Compare = less<Key>, class Allocator = allocator<Key> >

5. insert

//set最简单的insert函数只有一个参数
set set1;
for(list<int>::iterator it = list1.begin(); it != list1.end(); it++){
set1.insert(*it);
}

set和multiset定义的insert有些不同,下面是set的定义:

pair<interator, boo> insert(const value_type& x);

multiset的insert定义:

iterator insert(const value_type& x);

set中不允许有重复元素,所以不一定插入成功,所以需要返回一个bool,表明是否插入成功。

它们还提供一个关于位置的insert成员函数,这个位置不是插入的位置,插入的位置由比较函数确定,而是从该位置搜索插入位置。

iterator insert(iterator position, const value_type& x);

使用inserter插入迭代器:

copy(list1.begin(), list1.end(), inserter(multiset1, multiset1.end() ));

6. erase

//删除所有索引值为e的元素
multiset1.erase('e');
//删除第一个e元素
multiset1.erase(multiset.find('e'));
//删除一个区间,迭代器[i, j)
multiset.erase(i, j);

7. 访问器

lower_bound表示索引的第一个位置,upper_bound表示最后一个位置。

//multiset1: aaabccccddeeefhhhxy
multiset<char>::iterator i = multiset1.lower_bound('c');
multiset<char>::iterator j = multiset1.upper_bound('h')
//erase之后,multiset1值为: aaabxy
multiset1.erase(i, j);

如果lower_bound和upper_bound作用于同一个索引值,则可以使用equal_range,返回一对迭代器,上面的代码可以写为下面的形式:

pair<multiset<char>::iterator, multiset<char>::iterator> > p = multiset1.equal_range('s');
multiset1.erase(p->first, p->second);

另外,count函数可以获取索引值的个数:

int num = multiset1.count('s');

8. map && multimap

map和multimap类的模板定义:

template <typename Key, typename T, typename Compare = less<Key>,
class Allocator = allocator<pair<const Key, T> > >

9. 插入

map的insert函数需要求一个pair做参数。

map.insert(pair<const Key, T>);

也可以使用运算符[],比如

map[k] = t;

如果不存在索引值为k的元素,则插入元素(k, t),如果已经存在某个元素(k, t0),则以t代替t0。

还可以用如下的替换操作:

//i为map<Key, T>::iterator
i->second = t;
//索引值是const, 不能修改,下面的语句是错误的
i->first = k1;

10. 删除

和集合一样,可以通过索引或位置删除映射和多映射中的元素。

11. 访问器

有下面的访问器:

begin,end,size,empty,find,lower_bound,upper_bound,equal_range,count,operatar[]...

二、Miscellany

@author gr
@mail forgerui@gmail.com

###STL学习--关联容器的更多相关文章

  1. STL之关联容器的映射底层

    STL的关联容器有set, map, multiset, multimap.用于实现它们的底层容器有划入标准的rb_tree和待增加标准的hashtable. 底层容器rb_tree为上层容器提供了一 ...

  2. STL之关联容器---set, mutilset, map, mutilmap

    STL的容器分为序列容器和关联容器.它们所表达的数据结构各有不同: 序列容器:vector(变长数组), list(链表), queue(队列), heap(堆算法)等 关联容器:set/mutils ...

  3. 侯捷STL学习(十)--容器hashtable探索(unordered set/map)

    layout: post title: 侯捷STL学习(十) date: 2017-07-23 tag: 侯捷STL --- 第二十三节 容器hashtable探索 hashtable冲突(碰撞)处理 ...

  4. STL之关联容器

    关联容器包含map.set.multimap.multiset. 关联容器的特点是明显的,相对于顺序容器,有如下特点: 1.其内部是采用非线性的二叉树结构,具体的说是红黑树的结构原理实现的. 2.se ...

  5. STL学习笔记— —容器map和multimap

    简单介绍 在头文件<map> 中定义 namespace std { template <typename Key, typename T, typename Compare = l ...

  6. 【STL】关联容器 — hash_set

    容器hash_set是以hash table为底层机制的,差点儿所有的操作都是转调用hash table提供的接口.因为插入无法存储同样的键值,所以hash_set的插入操作所有都使用hash tab ...

  7. C++ STL学习之容器set和multiset (补充材料)

    一.set和multiset基础 set和multiset会根据特定的排序准则,自动将元素进行排序.不同的是后者允许元素重复而前者不允许. 需要包含头文件: #include <set> ...

  8. 【STL】关联容器 — hashtable

    C++ 11哈希表已被列入标准列.hashtable这是hash_set.hash_map.hash_multiset.hash_multimap的底层机制.即这四种容器中都包括一个hashtable ...

  9. STL - 常用关联容器代码 - set & multiset

    代码如下: /* 5. set & multiset */ set<string> cities{ "Braunschweig", "Hanover& ...

随机推荐

  1. 备份数据表为insert 脚本

    unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  2. gtest框架使用

    gtest文档说明: 由于公司单元测试的需要,自己花了大半天时间下载了一个gtest框架,使用了一些测试例子,总览了coderzh的玩转gtest测试框架,又看了几篇gtest博客,写下了以下内容,作 ...

  3. Java经典面试题

    1. Java中的异常处理机制的简单原理和应用. 当Java 程序违反了Java的语义规则时,Java虚拟机就会将发生的错误表示为一个异常.违反语义规则包括2种情况.一种是Java类库内置的语义检查. ...

  4. docker——Dockerfile创建镜像

    写在前面: 继续docker的学习,昨天用docker成功跑了tomcat,但是在centos中镜像跑的容器手动装jdk和tomcat,今天学习用Dockerfile创建镜像,并在上面搭建java环境 ...

  5. C#学习笔记(一):一些零散但重要的知识点汇总

    集合类型 数组 数组需要注意的就是多维数组和数组的数组之间的区别,如下: using System; namespace Study { class Program { static void Mai ...

  6. Stage3D学习笔记(六):旋转动画效果

    我们这节在上一篇代码的基础上再进一步,让显示的纹理进行旋转. 实现旋转,只需要每帧修改_modelViewMatrix的旋转角度即可,我们需要一个变量来记录旋转: //旋转度数 private var ...

  7. (Relax DFS专题1.2)POJ 2386 Lake Counting(使用DFS来计算有多少坨东西是连通的)

    题目大意:有N*M的矩阵稻田,'W'表示有积水的地方, '.'表示是干旱的地方,问稻田内一共有多少块积水,根据样例很容易得出,积水是8个方向任一方向相连即可. 题目大意:有N*M的矩阵稻田,'W'表示 ...

  8. 我眼中的PM

    我眼中的PM 1 我眼中的PM 1.1 人云“一个管理,半个专家”,我说“一个管理,两个专家” 如今,我发现我们不得不面对这样一个现实——角色兼职.我习惯上把项目分为三类:性命攸关的项目(涉及到人身安 ...

  9. cocos2d-x Touch

    转自:http://codingnow.cn/cocos2d-x/783.html 游戏跟视频最大的区别就是互动,玩家可以操控游戏中的角色,现在的移动设备几乎人手一台,基本上全部都是基于触屏操作的,今 ...

  10. navicat for mysql (10038)如何解决,远程无法连接问题

    ubuntu server下安装了MySQL 5.5数据库,然后在windows下通过Navicat for MySQL连接时,出现 Can't connect to mysql server on ...