容器

顺序容器

主要靠下标和迭代器进行操作。顺序性的主要靠下标,链式的靠迭代器访问。

包含了顺序型的容器和链式的容器。

连续型的包括:

  • vector:向量,可以快速扩展和删除元素,在队尾的操作有优势!
  • deque:双端队列,可以快速的从队首和队尾添加或者删除元素,适合双向的操作。
  • array:数组,大小必须是固定的。
  • string:字符串

链式的包括:

  • list:双向链表
  • forward_list:单向链表。没有size操作。

关联容器

简介

主要靠关键字进行访问。关联容器主要是分为两类:set类型的和map类型的。同时也可以按照有序和无序分类,也可以按照顺序保存和无序保存分类。

总共有8中类型额关联容器:

  • map:关键字-值,关键字唯一
  • set:关键字,关键字唯一
  • multimap:关键字-值,关键字可以重复
  • multiset:关键字:关键字可以重复
  • unordered_map:哈希函数组织的map,关键字唯一
  • unordered_set:哈希函数组织的set,关键字唯一
  • unordered_multimap:哈希函数组织的multimap,关键字不唯一
  • unordered_multiset:哈希函数组织的multiset,关键字不唯一

上述以unordered开头的都是无序的关联容器。关联容器都是支持模板类型操作的。

关联容器不支持顺序容器的那种与位置有关的操作,比如push_backpush_front等,这些操作无意义。关联容器的迭代是双向的。

有序关联容器的关键字必须定义比较函数,否则无法放入容器,因为容器需要靠<比较函数才能进行数据结构的构建。使用有序容器存储自定义的数据类型时,除了给出数据类型的模板之外,还要给出自定义的操作类型。不过我们一般都是重载运算符<进行操作。

#include <iostream>
#include <set>
using namespace std;class Data1{public:Data1(int _a,int _b=0,int _c=0):a(_a),b(_b),c(_c){}bool operator<(const Data1 &d){return a<d.a;}int a,b,c;
};int main(){set<Data1>s1;return 0;
}

pair数据类型,存在于utility头文件。该数据类型用于map大类的操作,具体有一下几个操作:

  • pair<T1, T2> p;声明一个pair
  • pair<T1, T2> p(v1, v2);声明并初始化
  • pair<T1, T2>p{v1, v2} ;声明并初始化
  • auto p=make_pair(v1,v2);初始化,编译器自动推断所有类型。
  • p.first:返回键值
  • p.second:返回对应的数据
  • p1 < p2:比较的是键值,对于其他的运算符同理。

主要操作

几个特性:

  • key_type:容器的关键字类型
  • mapped_type:每个关键字关联的类型,只适用于map类型
  • value_type:数据类型
    • 对于set类型,这与key_type相同
    • 对于map类型,为pair<const key_value, mapped_type>

上述说的类型是大类。

迭代操作

一般使用自动推导得到迭代器,迭代器是value_type类型的指针。

对于set来说,就是元素模板的类型;对于map来说,是pair<const key_value, mapped_type>类型。

注意,set的迭代器是const类型的,只能读不能修改,这很好理解,因为一旦修改键值,所有的排列顺序都要进行改变;而map的不能修改键值,但是可以修改键值对应的数据:

#include <iostream>
#include <map>
using namespace std;int main(){map<int,string>m{{1,"a"},{2,"b"}};for(auto it=m.begin();it!=m.end();it++){it->second="new";  // 在这里修改对应的数据}cout<<m[1]<<endl;   // 输出newreturn 0;
}

对于迭代操作,只要是有序容器,都是按照字典序输出的。

一般来说,关联容器的迭代器都是只读类型的,我们平时用的sort等的算法都不适用这种容器,但是可以使用find的成员给键值定位。也可以使用copy进行复制操作。

插入操作

单个键值的插入:

使用内置的insert成员进行操作。几个常用的操作:

  • c.insert(v),插入对应的valut_type类型的数据
  • c.emplace(args),对于单键值的关联容器,只有元素不存在的时候进行插入,多键值的直接插入;返回一个pair类型的数据,第一个是指向含有关键字的元素,第二个是bool,表示是否插入成功。
  • c.insert(b,e)b和e是迭代器,表示插入一个区间的value_type类型数据
  • c.insert(il)表示使用花括号的类型

上述的返回值都是一个pair,作用同上。

多个键值的插入:

不返回任何数据,因为总是可以进行数据插入。

删除操作

使用erase进行删除操作:

  • c.erase(k):删除关键字为k的元素,返回删除的个数,不存在返回0
  • c.erase(p):删除迭代器指向的元素,必须是内部的,不能是end()
  • c.erase(b,e):删除区间内的元素

map的下标操作

下标操作只适用于mapunordered_map,不能用于多键值的;同时,元素必须是非const类型的。set没有下标操作。两种数据类型:

  • c[k]:返回关键字是k的元素,如果k不存在,进添加这个关键字,并初始化
  • c.at(k):返回关键为k的元素,不存在抛出out_of_range异常

上述返回的都是mapped_type类型的数据。

访问操作

  • c.find(k):返回第一个迭代器,指向关键字是k的,不存在返回end()
  • c.count(k):返回关键字为k的个数
  • c.lower_bound(k):返回第一个迭代器,指向第一个关键字不小于k元素,不适于无序容器!
  • c.upper_bound(k):返回第一个迭代器,指向第一个关键字大于k的元素,不适于无序容器!
  • c.equal_range(k):返回一个pair,表示范围。如果不存在,成员均为end()

无序容器

无序容器使用hash函数和==进行运算。主要处理元素没有明显有序关系的情况,理论上有更好的性能,但是实际上需要多次进行工程验证效率。

无序容器的插入删除和有序容器基本一致,只是没有和序列有关的操作。无序容器使用了一个链式的桶状结构,性能取决于哈希函数的质量和桶的数量与大小。如果是自定义的数据类型,我们需要自己来说明哈希函数,否则不能直接使用。

#include <iostream>
#include <unordered_set>  // 注意头文件
#include <string>
#include <functional>
using namespace std;class Data{public:Data(int a,string s):n(a),str(s){}int n;string str;
};size_t hasher(const Data &d){return hash<string>()(d.str);
}bool cmp(const Data& d1, const Data &d2){return d1.str==d2.str;
}int main(){using SD_multiset=unordered_multiset<Data,decltype(hasher)*, decltype(cmp)*>;// 桶的大小,哈希函数,比较函数SD_multiset data_set(10,hasher,cmp);Data d(1,"hello");data_set.insert(d);return 0;
}

迭代器

迭代器是一个泛型的指针类型,只要是可迭代的容器,都可以使用迭代器。适配器不可以使用,比如stackqueuepriority_queue等的数据类型。

  • begin()是首元素
  • end()是尾后元素
  • 若容器是空的,则begin()==end()

迭代器的标准运算成员:

  • *iter取内容
  • iter->item取出内部的成员
  • ++iter指向下一个元素
  • --iter指向上一个
  • iter1==iter2判断是否指向同一个元素
  • iter1!=iter2不指向同一个元素的判定

使用了迭代器的循环体,不要向迭代器所属的容器添加元素!!!

非标准迭代器成员的运算符号根据具体的容器确定。

容器的适配器

容器的适配器是一个机制,使得某种事物看起来像另一种事物。给出基本类型和操作:

  • size_type:保证当前类型的最大对象的大小
  • value_type:元素的类型
  • container_type:实现适配器底层容器的类型
  • A a:创建一个A类型的空适配器a
  • A a(c):创建一个名为a的适配器,带有容器c的一个拷贝!!!
  • a.empty():判断是否是空,空返回true,否则是false
  • a.size():返回元素的个数
  • swap(a,b):交换a,b的内容,要求比素食同类型的元素,底层容器类型也必须相同
  • a.swap(b):同上

栈默认使用deque作为底层,队列默认使用dequepriority_queue默认使用vector作为底层。也可以自定义底层容器。需要注意的是:适配器不能进行迭代!!

C++容器,迭代器,容器的适配器相关推荐

  1. C++STL总结笔记(一)—— 容器和容器适配器

    文章目录 前言 一.概念 1.1 顺序容器 1.2 容器适配器 1.3 关联容器 二.程序示例 1. vector和Set自定义数据类型的访问 2.vector容器嵌套 3.list容器排序 4.pa ...

  2. STL 容器简介:C++ 容器:顺序性容器、关联式容器和容器适配器

    STL标准容器类简介 标准容器类 说明 顺序性容器 vector 从后面快速的插入与删除,直接访问任何元素 deque 从前面或后面快速的插入与删除,直接访问任何元素 list 双链表,从任何地方快速 ...

  3. QT学习笔记(九):遍历容器-迭代器(iterators)

    QT学习笔记(九):遍历容器-迭代器(iterators) 遍历容器 : 1.Jave风格: 2.STL风格: 3.foreach 关键字: 遍历容器 : 遍历一个容器可以使用迭代器(iterator ...

  4. C++11中容器迭代器操作总结

    C++11中标准容器迭代器操作总结 我发现有必要对各类容器迭代器的操作做一个小小的总结,本文中的内容大多来自于<C++ Primer>(第5版)中相关章节的内容.        1.下面列 ...

  5. C++中的容器(STL容器)container

    1.容器 容器(container)用于存放数据的类模板.可变长数组.链表.平衡二叉树等数据结构在STL中都被实现为容器.使用容器时,即将容器类模板实例化为容器类时,会指明容器中存放的元素是什么类型的 ...

  6. 关联容器----关联容器概述,关联容器操作,无序容器

    关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的.与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的. 关联容器支持高效的关键字查找和访问.两个主要的关联容器 ...

  7. 【STL四】序列容器——vector容器

    [STL容器]序列容器--vector容器 一.简介 二.头文件 三.模板类 四.成员函数 1.迭代器 2.元素访问 3.容量 4.修改操作 五.demo 1.容量reserve.capacity.s ...

  8. Docker 容器技术 — 容器存储

    目录 文章目录 目录 容器存储 数据卷管理 挂载时创建卷 创建卷后挂载 数据容器管理 容器存储 数据卷管理 核心选项: -v 宿主机目录:指定挂载到容器内的目录. 映射多个宿主机目录,只需要多写几个 ...

  9. Docker 容器技术 — 容器网络

    目录 文章目录 目录 CNM CNM 驱动接口 网络驱动 IPAM 驱动 Docker 原生网络驱动 Bridge 模式(默认) 用户自定义 Bridge 网络 Host 模式 外部访问容器(容器的端 ...

  10. Web服务器 Web容器 Servlet容器

    WEB服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务. WWW 是 Internet 的多媒体信息查询工具,是 Internet 上近年才发展起来的服务,也是 ...

最新文章

  1. 【青少年编程】【四级】从小到大排序
  2. PacBio But Not Illumina Technology Can Achieve Fast, Accurate and Complete Closure of the High GC, C
  3. Enterprise Manager Cloud Control 安装
  4. iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、view...
  5. matlab的离散求导,高手留步:MATLAB五阶拟合函数,求导后离散化,输出结果是星号...
  6. 帆软报表(finereport)单元格函数,OP参数
  7. BeetleX自定义http/websocket压测用例视频
  8. 显卡天梯图:2014最新显卡性能天梯图
  9. Ambari离线部署Hadoop集群踩到的坑
  10. x-requested-with 请求头 区分ajax请求还是普通请求
  11. phpadmin 安装
  12. utf-8、unicode区别与联系
  13. html调整div上下顺序,用了float后div块之间的上下顺序不对了_html/css_WEB-ITnose
  14. 前端js实现打印excel表格
  15. 20145202马超《java》实验5
  16. Wl,-rpath的格式问题,Wl,--rpath
  17. SWMM模型代码LID(Low Impact Development)模块分析
  18. python Word批量转PDF
  19. ChinaVis 2017
  20. maven报错问题汇总

热门文章

  1. java entrypoint_java – 有时只调用AuthenticationEntryPoint
  2. 终端操作MySQL数据库
  3. PyTorch报错“/.../Loss.cu: ... [59,0,0] Assertion input_val >= zero input_val <= one failed.”
  4. r语言去除字符串两端多余空格
  5. 用于Ubuntu 16.04和18.04的TensorFlow,Keras,Caffe,Caffe,CUDA,cuDNN和NVIDIA驱动程序的单行安装
  6. JS小技巧 ----- 关于 ... 运算符的使用场景
  7. GTK+图形化应用程序开发学习笔记(一)—概述
  8. this.grid is undefined
  9. JAVA——孪生素数
  10. Selenium WebDriver Api 知识梳理