顺序容器:具有单一类型元素的容器。
vector 快速随机访问,
list 快速插入/删除, #include <cliext/list>
deque 双端队列
顺序容器适配器: stack (后进先出栈), queue(先进先出队列), priority_queue(有优先级管理的队列)
#include <vector>
#include <list>
#include <deque>
初始化:
C<T> c;
C c(c2); c和c2具有相同的容器类型
C c(b, e); c的元素是只待其b和e标示的范围内元素的副本。
C c(n, t); n个值为t的元素创建容器, 其中值t是容器类型C的元素类型。或者容器类型必须有默认构造函数且形参为t。
C c(n); 创建有n值初始化元素的容器,容器类型必须有默认构造函数且没有形参。
必须支持赋值和复制的类型才能作为容器的元素类型,而比如IO库类型不支持复制和赋值,所以不能作为容器元素类型。
迭代器(一种检查容器内元素并便利元素的数据类型):
比如: vector <int>::integrator iter, iter2;
*iter; ++iter; iter++; --iter; iter--; iter == iter2; iter != iter2; //所有的标准库容器类型都适用。
对于vector 和deque(只有这两种容器提供快速随机的访问):
iter+n; iter-n; iter+= iter2; iter-= iter2; iter-iter2; >; <; >=; <=
迭代器范围:[ first, last) //end是指向最后一个元素的下一个元素
添加或者删除元素:
c.rbegin(); //指向容器c的最后一个元素
c.rend(); //指向容器c的第一个元素的前一个元素
c.push_back(T); //向容器尾部添加元素,所有容器类型都可用
c.push_front(T); //向容器前端添加元素,只适用于list和deque
c.insert(p, t); //在p元素前插入t元素,返回指向t的迭代器
c.insert(p, n, t); //在p元素前插入n个t元素,返回void类型
c.insert(p, b, e); //在p元素前插入迭代器b和e标记的范围内元素,返回void类型
注意:添加或删除元素会使迭代器
容器大小的操作:
c.size(); //返回容器c中的元素个数,返回类型为 c::size_type
c.max_size(); //返回容器c可容纳的最多元素个数,返回类型为c::size_type
c.empty() //返回标记容器大小是否为0的bool类型
c.resize(n); //调整容器c的大小使其能容纳n个元素,如果n<c.size();则删除多余的元素,否则采用值初始化新的元素
c.resize(n, t); //调整容器c的大小使其能容纳n个元素,如果n<c.size();则删除多余的元素,否则采用值t初始化新的元素
访问容器元素:
c.back(); //返回c的最后一个元素的引用,如果c为空,则未定义
c.front(); //返回c的第一个元素的引用,如果c为空,则未定义
c[n]; // 返回c的下标为n的元素的引用,若n<0 || n>c.size();则未定义,只适用与vector和deque
c.at[n]; // 返回c的下标为n的元素的引用,若n<0 || n>c.size();则未定义,只适用与vector和deque;异常抛出out_of_ranger异常
删除元素:
c.erase(p); //删除迭代器p所指向的元素,返回指向被删元素的下一个元素的迭代器
c.erase(b, e); //删除迭代器[b, e]之间的的元素,返回指向被删元素的下一个元素的迭代器
c.clear(); //删除容器c内的所有元素,返回void
c.pop_back(); //删除容器c的最后一个元素,返回void,如果c为空,则未定义
c.pop_front(); //删除容器c的第一个元素,返回void,如果c为空,则未定义
只适用于deque和list;
赋值和swap
c = c2; //删除容器c元素,copy c2元素至c
c.swap(c2); //交换c和c2的元素,速度快
c.assign(b, e); //将[b, e)元素复制到c,b,e必须不是指向c的迭代器
c.assign(n, t); //将c重新设置为n个值为t的元素的副本
c.reserve(n); //容器vector需预留多少个空间
c.capacity(); //容器的容量,当c.size()>c.capacity(),c.capacity()+=n;
容器适配器:让容器可以采用另一种工作方式
例如:deque<int> deq;
stack<int> stk(deq);
queue适配器要求关联的基础容器必须提供push_front运算,因此只能建立在list容器上,而不能建立在vector容器上,priority_queue要求提供随机访问功能,因此可以建立再vector或deque容器上,但是不能建立再list容器上。
stack 适配器
s.empty(); //栈为空,返回true
s.size(); //返回栈中元素个数
s.pop(); //删除栈顶元素
s.top(); //返回栈顶元素
s.push(item); //在栈顶压入新元素
所有的容器适配器都根据其基础容器类型所支持的操作来定义自己的操作,但是不能直接盗用基础容器的操作。
queue和priority_queue适配器
q.empty(); //队列为空,返回true
q.size(); //返回队列中元素个数
q.pop(); //删除队首元素元素
q.front(); //返回队列首元素值,只适用于队列
q.back(); //返回队列尾元素值,只适用于队列
q.top(); //返回优先级最高的元素,只适用于priority_queue
q.push(item); //对于queue在队尾插入元素,对于priority_queue在基于优先级的位置插入元素。
String
string s; //定义空string
string s(cp); //cp可以是一个string对象,也可以是cp(必须以null结束的)C风格的字符串。但是不包括null字符被复制到s;
string s(cp, n); //cp (指向数组,可以不以null结尾)的前n个字符被复制到s;
string s(s2, p2); //string s2的从下标p2开始的字符被复制到s;如果p2>s.size(), 未定义
string s(s2, p2, len); //string s2的从下标p2长度为len开始的字符被复制到s;如果p2>s.size(), 未定义无论len多少,最多有s2.size() – p2个字符被复制
p2, n, len 都为unsigned
is >> s; //从输入流is中读取一个以空白字符分割的字符串,写入s
os << s; //s写到输出流
getline(is, s); //从输入流is中读取一行字符写入s,可以包括空格
s1 + s2; //拼接产生新的string;
s1+=s2; //拼接到s1
==, !=, >, >=, <, <=
string 与容器共有的操作:
s.insert(p, t); //在迭代器p指向的元素之前插入一個值為t的新元素,返回指向新元素的迭代器
s.insert(p, n, t); //在迭代器p指向的元素之前插入n個值為t的新元素,返回指向新元素的迭代器
s.insert(p, n, t); //在迭代器p指向的元素之前迭代器[b, e)元素,返回void
s.assign(b, e); //用迭代器[b, e)元素替换s,对于string,返回s,对于容器返回void
s.assign(n, t); //s设置为n个值为t的元素的副本,返回s,对于容器类型返回v
s.erase(p); //删除迭代器p指向的元素,返回被删除元素的下一个元素;
s.erase(b, e); //删除[b, e) 之间的元素,返回被删除元素的下一个元素;
string特有的操作(以下操作返回s的引用):
s.insert(pos, n, c) //再下标为pos的元素前插入n个字符c
s.insert(pos, s2) //再下标为pos的元素前插入string s2
s.insert(pos, s2, pos2, len) //再下标为pos的元素前插入string s2 从下标pos2开始的len个字符
s.insert(pos, cp, len) //再下标为pos的元素前插入cp所指数组的前len个字符
s.insert(pos, cp) //再下标为pos的元素前插入以null结束cp指向字符串的副本
s.assign(s2); //s2副本替换s
s.assign(s2, pos, len); //s2从下标pos开始len个字符副本替换s
s.assign(cp, len); //cp所指数组的前len个字符副本替换s
s.assign(cp); //以null结束cp指向字符串副本替换s
s.erase(pos, len) //删除下标为pos开始的len个字符
s.substr(pos, n); //返回从s 下标pos开始的n个字符的string
s.substr(pos); //返回从s 下标pos开始的string
s.substr(); //返回string副本
args:
s2 //string
s2, pos2, len2 //s2位置pos2开始的长len2个字符
cp //指向以null结束数组的cp
cp, len2 //指向以null结束数组的cp的前len2个字符
n, c //字符c的n个副本
b2, e2 //迭代器
s.append(agrs); //将args串接在s后面,返回s的引用
s.replace(pos, len, args); //删除s位置pos开始的len个字符,用args代替
s.replace(b, e, args); //删除[b, e),元素,用args代替
string的查找操作:
args:
cp, pos //从pos开始查找以null结尾的cp,
cp, pos, n //从pos开始查找以null结尾的cp前n个字符
c, pos //从pos开始查找c,
s2, pos //从pos开始查找s2
s.find(args); //查找args第一次出现
s.rfind(args); //查找args最后一次出现
s.find_first_of(args); //查找args中任意字符第一次出现
s.find_last_of(args); //查找args中任意字符最后一次出现
s.find_last_not_of(args); //查找第一个不属于args的字符
s.find_last_ not_of(args); ///查找最后一个不属于args的字符
s.compare(s2); //比较s和s2,s>s2, return >0,other
s.compare(pos, len, s2); //比较s从pos开始的len个字符和s2
s.compare(pos1, len1, s2, pos2, len2); //比较s从pos1开始的len个字符和s2 从pos2开始的len2个字符
s.compare(cp); //比较s和cp指向的以null结尾的字符串
s.compare(pos, len,cp); //比较s从pos1开始的len个字符和cp指向的以null结尾的字符串
s.compare(pos, len,cp, n2); //比较s从pos1开始的len个字符和cp指向的以null结尾的字符串的前n2个字符
关联容器:支持通过键来高效地查找和读取元素
map 关联数组:元素通过键来存储和读取
set 大小可变的集合,支持通过键实现的快速存储
multimap 支持同一个键多次出现的map类型
multiset 支持同一个键多次出现的set类型
以上容器都是按顺序存储的。
pair类型(包含两个成员first, second)
pair<T1, T2> p1; //创建空的pair对象,它的两个元素分别是T1和T2类型
pair<T1, T2> p1(v1, v2); //创建空的pair对象,它的两个元素分别是T1和T2类型,分别初始化为v1, v2
make_pair(v1, v2); //以v1,v2创建一个新的pair对象,其元素类型分别是v1, v2的类型
p.first //返回p中名为first的公有成员
p. second //返回p中名为second的公有成员
p1 < p2 //先比较first,再比较second,真return true
p1 == p2 // first成员和second成员都相等时返回true
map 类型
#include<map>
map(k, v) m; //创建空map对象,其键和值的类型分别为k, v
map(k, v) m(m2); //创建空map2副本m,其键和值的类型必须相同
map(k, v) m(b,e); //m是存储迭代器b和e标记的范围内所有元素的副本,元素的类型必须能转换为pair<const k,v>
map(k, v)::key_type; //索引键的类型
map(k, v)::mapped_type; //键值的类型
map(k, v)::value_type; //pair类型,first成员具有const map(k, v)::key_type类型,second具有map(k, v)::mapped_type类型,second可以修改,first不能修改
map迭代器解引用产生一个pair对象
map<string, int>::iterator map_it = m.begin(),
map_it ->first = “hello”;
++ map_it ->second;
下标访问map;
m[“hello”] = 1;
注意:如果下标不存在,则会创造一个新元素,其实上例键值初始化为0然后再访问一次”hello”赋值为1;
map 操作:
m.insert(e); //e为m的value_type类型,如果e,first存在与m的键值中,则m不变,否则插入,返回一个pair类型对象,pair.first为指向键值为e.first元素的迭代器,pair.second为bool值,ture表示已存在
m.insert(b, e); //[b, e)标记的元素为m的value_type类型,如果e,first存在于m的键值中,则m不变,否则插入,返回void类型
m.insert(iter, e); //如果e,first不存在与m的键值中则创建,并以iter为起点搜索键值为e.first元素存储的位置,返回指向元素的迭代器
例子:
m.insert(map<string, int>::value_type(“hello”, 1));
m.insert(make_pair(“hello”, 1));
查找元素:
m.count(k); //返回m中k的出现次数,只能为0或者1
m.find(k); //m中如果存在键值k,返回指向该元素的迭代器,否则返回超出末端迭代器m.end();
删除元素(当元素被删除时,指向删除元素的迭代器将无效,不可做++, --):
m.erase(k); //删除键值为k的元素,返回size_type类型值,表示删除的元素个数
m.erase(p); //删除迭代器p所指向的元素,p必须指向m中具有的元素,且不能等于m.end(),返回void类型
m.erase(b, e); //删除迭代器b和e标记区间的元素,[b, e)必须指向m中的有效范围,可以相等,返回void类型
set类型:
除了不支持下标操作符,而且没有定义mapped_type类型,value_type也不是pair类型而是与key_type相同的类型外,其余操作与map相同(包括insert, find,count, erase,构造函数),总的来说set中存在的都是unique键值。
set<string> set1;
set1.insert(“hello”); //返回一个pair类型对象,first成员为一个指向键值”hello”的元素的迭代器,second为一个bool值,true为插入,false为元素已存在
vector <string> vec;
set1.insert(vec.begin(), vec.end());
multimap类型和multiset类型(允许一个键对应多个实例):
map和set类型容器所有操作都适用于multimap和multiset,如果某个键对应多个实例,则这些实例在容器中将相邻存放,对于insert则无论容器中有无键值都会插入。
某个键值对应的元素查找
1, multimap 的find(k)操作返回的是键值所对应的第一元素的迭代器,可以通过count(k)来遍历。
2, m.lower_bound(k); //返回指向不小于k的第一个元素,就是键值为k的第一元素,如果k不存在,则为该键应被插入的位置
m.upper_bound(k); //返回指向大于k的第一个元素
m.equal_range(k); //返回一个迭代器的pair对象,first成员为m.lower_bound(k), second成员为m.upper_bound(k);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?