一些话(废话 )
★ STL(标准模板库)在一些算法问题中很常用,我也只会一点,所以有必要整理一下,顺便让大家学学qwq
★dalao的话还是绕道吧真的很基础,不过也可以帮萌新指正一些错误
时隔大半年,我终于更新了~
栈(stack)
解释:他是一个先进后出的容器。先放进去其中的元素,后出来;而后放进去的元素先出来
eg. 先让1入栈,再让2入栈,那么2先出栈,1后出栈
1.使用前需要声明头文件< stack >
#include<stack>
2.定义与操作
定义:stack< 类型 > 名字
stack<int> s;
它的常用操作函数:
s.push(x) :将x入栈
s.pop() :弹出栈顶
s.top() :访问(返回)栈顶
s.size() :返回栈的元素个数
s.empty() :栈为空返回1,否则返回0
注意: 当栈为空时弹出栈顶 运行会出错 OJ上面会 Runtime Error
3.应用
简单应用
题目一:http://acm.wust.edu.cn/problem.php?cid=1328&pid=2
很基础,如果不会可以评论 我再贴代码qwq
稍微复杂一点的应用
题目二:http://acm.wust.edu.cn/problem.php?cid=1328&pid=4
解析:http://acm.wust.edu.cn/problem.php?cid=1328&pid=4
然后值得一提的是:栈的特性可以模拟dfs(深度优先搜索)
队列(queue)
解释:他是一个先进先出的容器。先放进去的元素,先出来;后放进去的元素,后出来~
eg. 先让1入队,再让2入队,那么1先出队,2后出队
1.使用前需要声明头文件< queue >
#include<queue>
2.定义与操作
定义: queue< 类型 > 名字
queue<int> q;
它的常用操作函数如下:
q.push(x) :将x入队
q.pop() :弹出队首
q.front() :访问(返回)队首
q.back() :访问(返回)队尾
q.size() :返回队列的元素个数
q.empty() :队列为空返回1,否则返回0
注意: 队列访问队首是 front 函数,不是 top 函数
4.应用
队列的特性可以用于 bfs(广度优先搜素)
优先队列(priority_queue)
解释:队列的用处较少,所以优先队列就诞生啦(纯属瞎BB~ ),他继承了queue的先进先出的特性,而其特性顾名思义,队中的元素都有一个优先级,优先级高的在前,优先级低的在后
1.需要声明头文件 < queue >
#include<queue>
2.定义
①不在定义的时候定义优先级的情况:一般类型是struct ,不然貌似没有方法定义优先级了(反正我不知道awa )
priority_queue<node> q;
想定义优先级的话 可以 通过重载来实现 代码如下
struct node
{
int m;
friend bool operator< (node a,node b) {return a.m>b.m;} //越小的元素 优先级越高
};
priority_queue<node> q; //定义优先队列
板子题 https://blog.csdn.net/weixin_43890662/article/details/87735056
②直接定义优先级:
priority_queue<int,vector<int>,less<int> > q; //定义优先队列
这是定义的越大优先级越高,想定义越小优先级越高就要把 less改成greater
3.常用操作函数
q.push(x) 将x入队
q.pop() 弹出队首
q.top() 访问(返回)队首
q.size() 返回队列的元素个数
q.empty() 队列为空返回1,否则返回0
注意:和队列不一样的是 这里的访问队首 是 top函数 不是 front函数
4.简单应用
可以试试这题 http://acm.wust.edu.cn/problem.php?id=1921&soj=0
解析:https://blog.csdn.net/weixin_43890662/article/details/87863381
双端队列(deque)
解释:双向队列,兼具了栈和队列的特性,双向都有口,两边都可进可出的容器
1.需要声明头文件< deque >
#include<deque>
2.定义与操作
定义都大同小异,在此及下面若都类似 则不再重复
常用函数:
q.push_front(1):从头部插入
q.pop_front(): 从头部弹出
q.push_back(1):从尾部插入
q.pop_back():从尾部弹出
q.front():访问头部元素
q.back():访问尾部元素
q.size(): 返回元素个数
q.clean():清空双端队列
3.应用
暂无,暂时还没用过awa
动态数组(vector)
解释:一般的数组的定义都是故意大于实际操作的大小(数组声明大小时不能用变量,数组定义大小就固定了,不能做到能屈能伸),动态数组的产生就大大优化了这些空间(能长能短,可大可小)
1.需要声明头文件< vector >
#include<vector>
2.定义与操作
动态数组的常规定义(我看老师写的好复杂花里胡哨的 ,可能是我这个低级了吧qwq)
vector<int> v;
常用的操作函数
v.push_back(x) :将x加入最后一位
v.pop_back(x) :将最后一位删除
v.size() :返回动态数组元素个数
v.empty() :若数组为空返回1,否则返回0
v.clear() :将数组全部清空
v.begin() :开始指针
v.end() :结束指针,指向最后一个元素的下一个位置
4.应用:
以我目前的水平的话,貌似用vector比较好的地方就是图论了,比如现在有100000个人,给出他们之间的一系列关系,你要怎么保存呢?定义一个1e5*1e5的数组?这是当然是定义二维动态数组来节省内存~ 而且那么大的二维普通数组根本开不出来
映射(map)
它提供了很好的一对一的关系,哪怕是一个字符串对应一个整数 也能轻松搞定,是一种关联式容器
1.需要声明头文件 < map >
#include<map>
2.定义与操作
定义: map<类型,类型> 名字
map<string,int> m
如果 “123” 对应 1 那就直接 m[“123”]=1 就完事了~
常用的操作函数:
m.begin():返回头部的迭代器
m.end(): 指向末尾的迭代器
m.count(x):返回x出现的次数,x必须是定义是的首类型(这里是string)
m.size():返回关系数
m.clear():删除所有元素
m.find(x):返回x出现的地址,注意同count
3.遍历
用迭代器遍历代码如下
first指第一元素 second指第二元素 不难理解叭
map<string ,int > m;
map<string ,int >::iterator it;
m["123"]=1;
m["124"]=3;
for(it=m.begin();it!=m.end();it++)
cout<<(*it).second<<endl;
集合(set)
详细见博客:https://blog.csdn.net/yas12345678/article/details/52601454
数学中的集合是不是要求 集合元素各不相同,这个容器也是如此。并且set会有一种自动排好序的感觉,比如访问尾部时 总是最大的元素
1.需要声明头文件 < set >
#include<set>
2.常用函数
s.begin() :返回set容器的第一个元素
s.end() :返回set容器的最后一个元素
s.clear() :删除set容器中的所有的元素
s.empty() :判断set容器是否为空
s.size() :返回当前set容器中的元素个数
s.insert(x):插入元素x
s.count(x):返回x出现次数,这里返回值不会超过1
更新于 2019/8/7
有待添加。。。
如果有不详细的地方,请指出qwq