queue
队列 ,先进先出。访问删除操作只能在队头进行,添加操作只能在队尾进行。不能访问除对头外的其他元素。头文件 #include<queue>
constructor
empty | 测试容器是否为空 |
size | 返回大小 |
front | 返回队首元素,不删除 |
back | 返回队尾元素,不删除 |
push | 入队,在队尾插入元素 |
push_back | |
pop_front | |
emplace | 构造并插入元素 |
pop | 出队,删除队首元素 |
swap | 交换内容 |
priority_queue 优先队列
默认大的先出队,想使小的先出队,可定义
priority_queue<int,greater> q;
对于非基本数据类型——重载比较运算符
Struct node{ int x, y; bool operator < (node a, node b){ return a.x > b.x; } } Priority_queue<node> q;
例题
02_M_ugly num
#include <iostream> #include <queue> #include <set> #include <vector> using namespace std; typedef long long ll; const int th=1500; int main(){ int ug[3]={2,3,5},i,j; ll x,y; priority_queue< ll,vector<ll>,greater<ll> > ugnum; set<ll> se; ugnum.push(1); se.insert(1); for(i=1;i<=th;i++){ x=ugnum.top(); ugnum.pop(); for(j=0;j<3;j++){ y=x*ug[j]; if(!se.count(y)){ se.insert(y);ugnum.push(y); } } } cout<<"The 1500'th ugly number is "<<x<<"."<<endl; }
vector
vector是一个能够存放任意类型的动态数组。头文件#include<vector>
· 定义和初始化
vector<T>v1 | v1是空vector,元素是T类型的,默认初始化 |
vextor<T>v2(v1) | v2中包含v1所有元素的副本 |
vector<T>v2=v1 | |
vector<T>v3(n,val) | v3包含n个重复元素,每个元素的值都是val |
vector<T>v4(n) | v4包含n个重复执行值初始化的元素 |
vector<T>v5{a,b,c,...} | v5包含初始值葛素的元素,被赋予相应的初始值 |
vector<T>v6={a,b,c,...} | |
vector<int>b(a.begin(),a.begin()+3) | 将a向量中第0个到第二个作为b向量的初始值 |
vector<int>a(&n[1],&n[4]) | 将n[1]-n[4]范围内的元素作为向量a的初始值 |
· vector支持的操作
v.empty() | v为空返回true,否则返回false |
v.size() | 返回v中元素个数 |
v.push_back(t) | 向v的末尾添加一个值为t的元素 |
v.pop_back() | 删除v末尾的元素,如果v为空,行为未定义 |
v[n] | 返回v中第n个位置上的元素的引用,位置n从0开始计 |
v.at(n) (cin>>v.at(0);) | 返回v中第n个位置上的元素的引用,下标越界抛出异常 |
v.clear | 清空向量中的元素 |
v1 = v2 | 赋值 |
v = {a,b,c,...} | 替换 |
v1 == v2 v1 != v2 | v1和v2相等当且仅当他们的元素数目相同且对应位置元素相同 |
<,<=,>,>= | 以字典顺序进行比较 |
a.insert(a.begin(), 10) ; //将10插入到向量a的起始位置前 a.insert(a.begin(), 3, 10); //将10分别插入到向量a的0-2处 b.insert(b.begin(), a.begin(), a.end()); //将a插入到b.begin前 a.erase(a.begin()); //将起始位置的元素删除 a.erase(a.begin(), a.begin() + 3); //将a的0-3处元素删除 a.swap(b); //将向量a与向量b交换
访问:迭代器
vector<int>::iterator it; for(it=a.begin();it!=a.end();it++) cout<<*it<<" ";
vector<T>类型对象的下标类型是vector<T>::size_type。
list
线性的双向链表,相对于verctor占用更多内存。头文件 #include<list>
list<string>s; s.push_back("world"); //插入 s.push_front("hello"); list<string>::iterator it; //遍历 for(it = s.begin(); it != s.end();t++) cout<<*it<<" ";
主要函数
begin() | 返回指向第一个元素的迭代器 |
end() | 返回末尾的迭代器 |
front() | 返回第一个元素 |
back() | 返回最后一个元素 |
insert() | 插入一个元素到list中 |
remove_if() | 按指定条件删除元素 |
clear() | 删除所有元素 |
empty() | 判断是否为空 |
pop_back() | 删除最后一个元素 |
pop_front() | 删除第一个元素 |
push_back() | 在末尾添加一个元素 |
push_front() | 在头部添加一个元素 |
reverse() | 把list的元素倒转 |
size() | 返回元素个数 |
sort() | 排序 |
splice() | 合并两个list |
swap() | 交换两个list |
unique() | 删除重复元素 |
find进行list查找元素x
(vector是顺序容器,没有find函数
vector<int> v; vector<int>:: iterator it; it = find(v.begin(), v.end(), x); cout << *it << endl;
stack
栈又名堆栈,是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。头文件 #include<stack>容器类型默认由双端队列deque实现,只允许在栈的尾部进行入栈和出栈操作。
基本用法:
empty() | 判断是否为空 |
size() | 返回栈的元素个数 |
top() | 返回栈顶元素 |
push() | 入栈 |
pop() | 出栈,无返回值 |
例题
02_J_rails
多组输入输出,每组输入第一行为列车长度,之后为列车车厢排列(以“0”标记结束)判断是否能够得到该排列输出“Yes”or“No”,每组输出之间空一行,以“0”标记输入结束。
AC代码:
#include <iostream> #include <stdio.h> #include <stack> const int MAX=1000; using namespace std; int main(){ int n,tra[1000]; int i; //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); stack<int>s; scanf("%d",&n); while(n!=0) { while(scanf("%d",&tra[0])==1&&tra[0]!=0){ for(i=1;i<n;i++){ scanf("%d",&tra[i]); } int A=1,B=0; bool ok=1; while(B<n){ if(A==tra[B]){++A;++B;} else if(!s.empty()&&s.top()==tra[B]){ s.pop();++B; } else if(A<=n){ s.push(A);++A; //等价于s.posh(A++); } else {ok=0;break;} } printf("%s ",ok ? "Yes":"No"); } scanf("%d",&n); printf(" "); } return 0; }
02_K_balance
给定一串由()和[]组成的字符串。如果我们规定以下的字符串是合法的字符串:
(1) 如果是空串,那么合法字符串。
(2) 如果A、B是合法的,那么AB也是合法的字符串。
(3) 如果A是合法的,那么(A)和[A]都是合法的字符串。
输入n表示有n个字符串,空行合法,输出“Yes”or“No”。
AC代码:
#include <stdio.h> #include <iostream> #include <stack> #include <string.h> using namespace std; int main(){ //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int n,lo,i,t; string ch; cin>>n; t=n+1; while(t--){ getline(cin,ch,' '); bool ok=1; if(ch=="0")ok=1; stack<char> s; lo=0;i=0; while(ch[i]){ ++lo; ++i; } for(i=0;i<lo;i++){ if(ch[i]=='('){s.push(ch[i]);} else if(ch[i]=='['){s.push(ch[i]);} else if(!s.empty()&&ch[i]==']'&&'['==s.top()){ s.pop(); } else if(!s.empty()&&ch[i]==')'&&'('==s.top()){ s.pop(); } else { ok=0; break; } } if(s.size())ok=0; if(t!=n)printf("%s ",ok?"Yes":"No"); } return 0; }
duque
双端队列,在功能上合并了vector和list
优点:1、支持[ ]操作符和vector.at()
2、在内部方便的进行插入和删除操作
3、可在两端进行push、pop
缺点:占用内存多
map
set
STL常用算法
unique(v.begin(), v.end()); //将相邻重复元素全部放到最后 sort(v.begin(), v.end()); //排序,默认从小到大 a.find(‘c’, i) //在a中从第i个位置开始找’c’,第二个参数可省略 count(v.begin(), v.end(), x) //在v中统计x出现次数 copy(v.begin(), v.end(), u.begin());//将v中元素复制到u中 reverse(v.begin(), v.end()); //将v中元素翻转