STL容器用法总结

vector 向量

可以说就是一个动态的数组,可以动态的增减容器中的元素数量。
需要头文件#include <vector>

定义方式:vector<数据类型> 变量名称;
size() //返回元素个数,时间复杂度O(1)
empty() //返回是否为空,是则返回true,O(1)
clear() //清空该数组
front()/back() //返回首元素a[0]/尾元素a[n-1]
push_back() //在数组的最后面插入一个元素
pop_back() //删除数组的最后一个元素
erase() //删除迭代器指向的元素
begin() //返回一个迭代器,它指向容器vector的第一个元素(关于迭代器,最后会讲到)
end() //返回一个迭代器,它指向容器vector的最后一个元素的下一个位置
[] //支持取下标,即a[0](注:大部分的stl容器其实都不支持这个操作)
注:支持比较运算,按字典序
举例:

vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
cout<<a.size()<<endl;   //输出3
cout<<a[0]<<' '<<a.front()<<endl;   //输出都为1
cout<<a[a.size()-1]<<' '<<a.back()<<endl;  //输出都为3
a.push_back(4);
cout<<a.back()<<endl;    //输出为4
a.pop_back();
cout<<a.back()<<endl;    //输出为3

pair

等价于有里面两种元素的结构体
pair 不需要头文件

定义方式:pair<数据类型1,数据类型2> 变量名称;
first, 第一个元素
second, 第二个元素
支持比较运算,以first为第一关键字,以second为第二关键字(字典序)
举例:

pair<int,char> a;
a.first=1;
a.second=a;
cout<<a.first<<' '<<a.second<<endl;   //输出1 a

string 字符串

char字符串的升级版。
需要头文件#include <string>

定义方式:string 变量名称;
size()/length() //返回字符串长度,这两个等价,时间复杂度O(1)
empty() //返回是否为空,是则返回true
clear() //清空该字符串
find() //查找某个字符或字符串,返回该字符串的开始下标
substr(起始下标,(子串长度)) //返回子串
c_str() //返回字符串所在字符数组的起始地址,即将一个string类型的字符串转化为char类型的字符串
to_string() //将其他类型转化为string类型
[] //支持下标运算
支持加法操作与比较运算,按字典序
举例:

string s;
s=(string)"abcd"+(string)"efgh";  //之后s为"abcdefgh"
cout<<s.size()<<' '<<s.length()<<endl;  //都输出8
cout<<s<<endl;    //输出整个字符串"abcdefgh" 
for(int i=0;i<s.length();i++)   //与上面的等价
cout<<s[i];
cout<<endl;

int a=123;  string b;
b=to_string(a);        //b为"123"
//strlen()为char类型的函数,所以直接strlen(s)会报错
cout<<strlen(s.c_str())<<endl;   //但这样就可以使用了,返回8
cout<<s.find("bc")<<endl;     //b的下标为1,所以输出1
cout<<s.substr(0,4)<<endl;    //开始位置为s[0],长度为4.输出"abcd"
cout<<s.substr(4)<<endl;      //未规定长度,则默认为最长
                              //开始位置为s[4],一直到s[7].输出"efgh"

stack 栈

维护一个数据结构:栈 的容器
需要头文件#include <stack>

定义方式:stack<数据类型> 变量名称;
size() //同上
empty() //同上
push() //向栈顶插入一个元素
top() //返回栈顶元素
pop() //弹出栈顶元素
举例:

stack<int> st;
st.push(1);
st.push(2);
cout<<st.top()<<endl;   //输出2
st.push(3);
cout<<st.top()<<endl;   //输出3
st.pop();
cout<<st.top()<<endl;   //输出2

queue 队列

维护一个数据结构:队列 的容器
需要头文件:#include <queue>

定义方式:queue<数据类型> 变量名称;
size() //同上
empty() //同上
push() //向队尾插入一个元素
front() //返回队头元素
back() //返回队尾元素
pop() //弹出队头元素
举例:

queue<int> q;
q.push(1);
q.push(2);
q.push(3);
cout<<q.size()<<endl;   //输出3
cout<<q.front()<<' '<<q.back()<<endl;   //输出为1 3
q.pop();
cout<<q.front()<<' '<<q.back()<<endl;   //输出为2 3

priority_queue 优先队列(堆)

维护一个数据结构:堆 的容器
堆的特点(大/小根堆):堆顶元素保证为堆中元素的最大/小值

需要的头文件:#include <queue>
定义方式:priority_queue<数据类型> 变量名称; (默认为大根堆)
定义成小根堆的方式:priority_queue<int,vector<int>, greater<int> > q;
size() //同上
empty() //同上
push() //插入一个元素,时间复杂度O(log n)
top() //返回堆顶元素,O(1)
pop() //弹出堆顶元素,O(log n)
举例:

以小根堆为例
priority_queue<int,vector<int>,greater<int> > heap;
heap.push(1);
heap.push(2);
heap.push(3);
cout<<heap.top()<<endl;    //输出最小值 1
heap.pop();    //弹出堆顶元素(1)
cout<<heap.top()<<endl;    //输出最小值 2

deque 双向队列

可以看成一个双向开口的数组,可以向两端插入/删除元素。
注意:双向队列的效率比较低(具体多低我也不知道),所以能不用尽量别用。
需要的头文件:#include <deque>

定义方式:deque<数据类型> 变量名称;
size() //同上
empty() //同上
clear() //同上
front()/back() //返回头元素/尾元素
push_back()/pop_back() //向队尾插入一个元素/删除队尾元素
push_front()/pop_front() //向队头插入一个元素/删除队头元素
begin() //返回一个迭代器,它指向容器deque的第一个元素
end() //返回一个迭代器,它指向容器deque的最后一个元素的下一个位置
[] //支持下标运算
举例:

这个就不举例了,和上面的那些都差不多,而且deque也并不常用。

set/multiset/unordered_set

实现原理:set/multiset 基于平衡二叉树(红黑树)
unordered_set 基于哈希表

该容器的特点:
set:自动排序、自动去重
multiset:自动排序、不去重
unordered_set:无序、自动去重
该类容器中的元素的值不可修改

需要的头文件:
set/multiset:#include <set>
unordered_set:#include <unordered_set>
定义方式:set / multiset / unordered_set<数据类型> 变量名称;
size() //同上
empty() //同上
clear() //同上
insert() //插入一个数
find() //查找一个数,返回迭代器的位置,未找到则返回end()
count() //返回某一个数的个数
erase() //(1) 输入是一个数x,删除所有x。O(k + logn) (2) 输入一个迭代器,删除这个迭代器
begin() //同上
end() //同上
下面的unordered_set没有
lower_bound(x) //返回大于等于x的最小的数的迭代器
upper_bound(x) //返回大于x的最小的数的迭代器
set/multiset 增 删 查 改 的效率为O(log n)
unordered_set 增 删 查 改 的效率为O(1)

举例:

以set为例
set<int> a;
a.insert(1);
a.insert(3);
a.insert(2);
cout<<a.count(2)<<endl;  //输出1
a.insert(2);
cout<<a.count(2)<<endl;  //因为set自动去重,还是输出1
注:遍历set容器的方法只有用迭代器或者范围for循环,这些后面会说

map/multimap/unordered_map 映射

将一种类型的变量与另一种类型的变量映射到一起。非常常用!(除了multimap)
实现原理:map/multimap 基于平衡二叉树(红黑树)
unordered_map 基于哈希表

该容器的特点:
map:自动去重复、有序(不过对于map这一类来说,有没有序/去不去重 一般没什么关系)
multimap:不去重、有序
unordered_map:无序、自动去重
该类容器中第一关键字的值不能修改。

需要的头文件:
map/multimap:#include <map>
unordered_map:#include <unordered_map>
定义方式:map / multimap / unordered_map<数据类型1,数据类型2> 变量名称;
size() //同上
empty() //同上
clear() //同上
insert() //插入的数是一个pair类型,它的两个数据类型与map容器的两个数据类型一致
erase() //输入的参数是pair或者迭代器
count() //返回某一个数的个数
begin() //同上
end() //同上
不过对于map这一类来说,上面的那些都不重要!重要的是下面这个:
[] //注意multimap不支持此操作(这也是它不常用的原因)。 对于map时间复杂度是 O(logn),unordered_map是O(1)
举例:
1 10 100 1000
字典

bitset 位图 (压位)

相当于一个二进制的数组,并且可以直接用01串赋值。也可以作为一个整数来使用。常用于除了位运算的操作。
需要的头文件: #include <bitset>
定义方式:bitset<位数> 变量名称;
位运算都可以用: 与、或、非、异或,左移,右移
size() //返回大小(位数)
count() //返回序列中1的个数
any() //判断是否有1
none() //判断是否没有1
all() //判断是否全是1
set() //把序列中每一位都全都变成1
set(p) //将第p + 1位变成1
set(p, x) //将第p + 1位变成x
reset() //把序列中每一位都全都变成0
reset(p) //将第p + 1位变成0
flip() //将序列中的每一位取反
flip(p) //将第p + 1位取反
to_ullong() //返回它转换为unsigned long long的结果,如果超出范围则报错
to_string() //返回它转换为string的结果

举例:

bitset<5> b;        //00000
b=5;                //将5转换为二进制赋给b
cout<<b<<endl;      //00101
cout<<b.count()<<endl;  //2
cout<<b.any()<<endl;    //1
cout<<b.none()<<endl;   //0
cout<<b.all()<<endl;    //0
for(int i=0;i<b.size();i++)     //1 0 1 0 0
     cout<<b[i]<<' ';
cout<<endl;   
//=============================
cout<<b.flip()<<endl;   //11010
cout<<b<<endl;          //11010

遍历容器的几种方法

一.范围for循环

这是c++11中的一个新语句。它可以遍历某个容器/数组中全部的元素。

以multiset为例
multiset<int> a;
a.insert(1);
a.insert(5);
a.insert(3);
a.insert(2);
a.insert(4);
a.insert(1);
for(auto it:a)    //输出为1 1 2 3 4 5 
cout<<it<<' ';
二.迭代器

C++ 的 STL 为每一种容器都定义了一种迭代器类型,迭代器是一种检查容器内元素并遍历元素的数据类型,C++ 中,对容器的访问操作更趋向于是用迭代器而非下标操作,只有少数容器(如 vector)支持下标操作访问容器元素。

迭代器类型可以用 * 操作符来访问迭代器所指向的元素,以 *iter = 0 为例,假设 it 指向 vector 对象 v 的第一个元素,那么 *iter 与 v[0] 就是指向同一个元素,那么 *iter = 0 就是将这个元素赋值为 0,同数组类似,迭代器可以使用自增、自减操作符向前、向后移动迭代器指向容器中的下一个元素。

迭代器的常用操作:

  • *iter:对 iter 进行解引用,返回迭代器 iter 指向的元素的引用
  • iter->first:对 iter 进行解引用,获取指定元素中名为 first 的成员,等效于 (*iter).first
  • ++iter、iter++:给 iter 加 1,使其指向容器的下一个元素
  • –iter、iter–:给 iter 减 1,使其指向容器的前一个元素
  • iter1==iter2:比较两个迭代器是否相等
  • iter1!=iter2:比较两个迭代器是否不等

几乎每种容器都定义了一对 begin()、end() 函数,用于返回相应的迭代器,如果容器中有元素的话,由 begin() 返回的迭代器指向第一个元素,而由 end() 返回的迭代器指向容器中最后一个元素的下一个位置,其没有指向任何实际的元素,它只是起一个标志的作用,表示已处理完容器中的所有元素。由于 end() 返回的迭代器不指向任何元素,因此不能对它进行解引用(*)或自增(++)操作。

以multiset为例
multiset<int> a;
a.insert(1);
a.insert(5);
a.insert(3);
a.insert(2);
a.insert(4);
a.insert(1);
multiset<int>::iterator it;       //定义一个迭代器
for(it=a.begin();it!=a.end();it++)    //遍历方法
cout<<*it<<' ';                           //输出为1 1 2 3 4 5 

//除了正向迭代器外,还有反向迭代器,二者唯一的区别在与反向迭代器会反向遍历容器
multiset<int>::reverse_iterator rit;       //定义一个反向迭代器
for(rit=a.rbegin();rit!=a.rend();rit++)    //遍历方法
cout<<*rit<<' ';                           //输出为5 4 3 2 1 1 
  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwz_159

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值