1.2 基础STL
1.2.1 vector
#include <vector>
| 成员函数 | 简介 |
|---|---|
vector<Type> v |
定义向量,Type为数据类型,v为向量名字 |
v[i] |
返回向量中下标为i的元素 |
v.at(i) |
返回向量中下标为i的元素,会进行越界检查 |
v.front() |
返回第一个元素 |
v.back() |
返回最后一个元素 |
v.push_back(a) |
在尾部添加一个元素a |
v.pop_back() |
删除最后一个元素 |
v.size() |
返回元素个数 |
v.empty() |
检查向量是否为空 |
v.clear() |
清空向量中所有元素 |
v.resize(n) |
调整向量大小为n,如果变大会用默认值填充,变小则删除多余元素 |
v.reserve(n) |
预留容量,但不改变元素个数 |
v.capacity() |
返回当前容量 |
v.insert(pos, a) |
在pos位置前插入a,返回新插入元素的位置 |
v.erase(pos) |
删除pos位置的元素,返回下一个元素的位置 |
v.begin() |
返回指向第一个元素的迭代器 |
v.end() |
返回指向最后一个元素之后位置的迭代器 |
vector是非常常用的一个STL容器,虽然名字叫做向量,但在实际使用时,常将其作为一个动态数组来使用,也极少称之为向量。
在需要定义数组时,经常可以使用vector,将其全部初始化为0,并给它稍大的空间,以防越界,常用的范围是1~n,0和n+1则不被使用:
vector<int>v(n+2,0);
除了在定义时初始化,也可以使用v.reserve(n+2)来预分配空间,需要避免频繁push_back导致多次扩容。
vector使用的Type也可以是另一个STL容器,例如vector<vector<int>>,这类似于一个二维数组,也可以进行初始化,但其中的每个元素都是一个vector<int>,这些元素又组成了一个vector。
vector<vector<int>> a(n+2, vector<int>(n+2, 0));
迭代器,iterator,可以理解为一个指向容器中元素的指针,通过迭代器可以遍历容器中的所有元素。
例如v.begin(),返回的就是v[0]的地址,就像我们处理指针一样,如果我们想要得到v[0]的值,就需要解引用,也就是*it。
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
v.end()返回的是最后一个元素的下一个位置,因此在这里使用it < v.end()也是等效的,但并不够通用,并不是所有STL容器的迭代器都可以这样写,因为这样比较的前提是区间连续。
如果数据从v[1]开始存储,那么就应该从v.begin()+1开始遍历。
需要注意的是,在向vector插入或删除元素后,原有的迭代器可能会失效,需要重新获取。
1.2.2 queue
#include <queue>
| 成员函数 | 简介 |
|---|---|
queue<Type> q |
定义队列,Type为数据类型,q为队列名字 |
q.push(item) |
将item插入队列最后 |
q.front() |
返回队首的元素,即最早插入队列的 |
q.pop() |
删除队首的元素 |
q.back() |
返回队尾的元素,即刚刚插入队列的 |
q.size() |
返回元素个数,这个数字一定是unsigned int的 |
q.empty() |
检查队列是否为空,如果是空的,则返回true |
队列,它是先进先出的,只能在队尾插入数据。
需要注意的是,队列并没有clear()函数,当你需要清空队列,不妨考虑q = queue()。
1.2.3 deque
#include <deque>
| 成员函数 | 简介 |
|---|---|
deque<Type> dq |
定义双端队列,Type为数据类型,dq为队列名字 |
dq[i] |
返回队列中下标为i的元素 |
dq.front() |
返回队首 |
dq.back() |
返回队尾 |
dq.pop_front() |
删除队首 |
dq.pop_back() |
删除队尾 |
dq.push_front(a) |
在队首添加一个元素a |
dq.push_back(a) |
在队尾添加一个元素a |
dq.size() |
返回元素个数,这个数字一定是unsigned int的 |
dq.empty() |
检查队列是否为空,如果是空的,则返回true |
dq.clear() |
清空队列 |
双端队列,既可以在队首插入数据,也可以在队尾插入数据。
1.2.4 priority_queue
#include <queue>
| 成员函数 | 简介 |
|---|---|
priority_queue<Type, Container, Function> pq |
定义优先队列,Type为数据类型,Container是底层容器,默认为vector,Function是排序方式,默认为less |
pq.push(item) |
将item按照排序方式入队 |
pq.top() |
返回优先级最高的元素 |
pq.pop() |
删除优先级最高的元素 |
pq.size() |
返回元素个数 |
pq.empty() |
检查该优先队列是否为空 |
优先队列,默认使用less<Type>,得到大根堆,即顶部为最大值;使用greater<Type>得到小根堆,即顶部为最小值。
1.2.5 stack
#include <stack>
| 成员函数 | 简介 |
|---|---|
stack<Type> st |
定义栈,Type为数据类型,st为栈名字 |
st.push(item) |
将item放到栈顶 |
st.top() |
返回栈顶的元素,即最晚送入栈的 |
st.pop() |
删除栈顶的元素 |
st.size() |
返回元素个数,这个数字一定是unsigned int的 |
st.empty() |
检查栈是否为空,如果是空的,则返回true |
栈,它是先进后出的,只能在栈顶插入数据。
1.2.6 list
#include <list>
| 成员函数 | 简介 |
|---|---|
list<Type> li |
定义链表,Type为数据类型,li为链表名字 |
li.front() |
返回第一个节点 |
li.back() |
返回最后一个节点 |
li.pop_front() |
删除第一个节点 |
li.pop_back() |
删除最后一个节点 |
li.push_front(a) |
在首部添加一个节点a |
li.push_back(a) |
在尾部添加一个节点a |
li.size() |
返回节点个数 |
li.empty() |
检查链表是否为空 |
li.clear() |
清空链表中所有节点 |
li1.swap(li2) |
交换两个链表中的数据 |
li.remove(a) |
删除链表里所有数据为a的节点 |
li.unique() |
去除重复数据 |
li.reverse() |
反转数据 |
li.sort() |
升序排列 |
双向链表,一个很大的特点是,所储存的元素在物理意义上是非连续、非顺序的,适合频繁在中间插入删除的情况。
特别的,链表不能使用algorithm中的sort,但自带有sort成员函数。
1.2.7 map
#include <map>
| 成员函数 | 简介 |
|---|---|
map<KeyType, ValueType> m |
定义映射,KeyType为键类型,ValueType为值类型,m为映射名字 |
m[key] |
返回键key对应的值,如果key不存在,则会插入一个具有该键的元素,值初始化 |
m.at(key) |
返回键key对应的值,如果key不存在,抛出异常 |
m.insert(pair) |
插入一个键值对pair,如果键已存在,则插入失败 |
m.erase(key) |
删除键为key的元素 |
m.find(key) |
返回键为key的元素的迭代器,如果没找到则返回m.end() |
m.count(key) |
返回键为key的元素个数,对于map来说,只能是0或1 |
m.size() |
返回元素个数 |
m.empty() |
检查映射是否为空 |
m.clear() |
清空映射中所有元素 |
m.begin() |
返回指向第一个元素的迭代器 |
m.end() |
返回指向最后一个元素之后位置的迭代器 |
映射,其中的KeyType都是唯一的。
一个常用的地方是map<char,int>,可以用于储存char型元素出现的次数。
map<char, int>::const_iterator it;
for(char ch='a';ch<='z';ch++){
it=hash.find(ch);
if(it==hash.end()||it->second<1){
return false;
}
}
1.2.8 set
#include <set>
| 成员函数 | 说明 |
|---|---|
set<Type> s |
定义集合,Type为数据类型,s为集合名字 |
s.insert(item) |
插入元素item |
s.erase(item) |
删除元素item |
s.erase(pos) |
删除迭代器pos指向的元素 |
s.find(item) |
返回元素item的迭代器,如果没找到则返回s.end() |
s.count(item) |
返回元素item的个数,对于set来说,只能是0或1 |
s.size() |
返回元素个数 |
s.empty() |
检查集合是否为空 |
s.clear() |
清空集合中所有元素 |
s.begin() |
返回指向第一个元素的迭代器 |
s.end() |
返回指向最后一个元素之后位置的迭代器 |
s.lower_bound(item) |
返回第一个不小于item的元素的迭代器 |
s.upper_bound(item) |
返回第一个大于item的元素的迭代器 |
集合,也就是每个元素仅会出现一次。
1.2.9 pair
#include <utility>
特别的,#include <map>中包含了pair的实现。
| 成员函数 | 简介 |
|---|---|
pair<Type1, Type2> p |
定义pair,Type1和Type2为数据类型,p为pair名字 |
p.first |
访问pair的第一个元素 |
p.second |
访问pair的第二个元素 |
make_pair(a, b) |
创建一个pair,第一个元素为a,第二个元素为b |
对,将两个不同类型的值组合成一个有序对,一个常见的用处是,作为将两个元素绑在一起的结构体的代替品。
