#该文章参考华文慕课——>程序设计实习#
C++学习笔记——STL库(标准模板库)
标准模板库(STL)就是一些常用数据结构和算法的模板的集合。其中有两个概念比较重要,一个是容器,一个是迭代器。
容器:类模板 迭代器:用来去容器中的元素,类似于指针
1.容器
容器分为三种:顺序容器、关联容器、容器适配器。
1.1顺序容器
vector:动态数组,可随机存取,可在尾部增删,也可在中间插入(较慢)
deque:双向队列:可随机存取,可在首尾增删
list:双向链表:不支持随机存取,可在任意位置增删(较快)
1.2关联容器
特点:元素是排序的——>为了查找方便。插入数据的位置不能任意,由其值大小决定。
set/multiset:set容器不允许同一元素出现两次,mutiset可以
map/mutimap:map容器不允许同一元素pair(键相同的)出现两次,mutimap可以
1.3容器适配器
stack:堆栈,后入先出
queue:队列,先入先出
priority_queue:优先级最高先出
2.迭代器
vector<int>::const_iterator(只能访问不能修改)\iteator(可以访问也可以修改)\reverse_iterator(反向迭代)
2.1双向迭代器
双向迭代器只能(++)p++,(--)p--,赋值p=p1,判断p==p
支持双向迭代器的容器有 list、set、mutiset、map、mutimap
2.2随机访问迭代器
可比较大小p<p1,p>p1,可 p+i
支持随机访问迭代器的容器有 vector、deque
2.3注意
容器适配器(stack、queue、priority_queue)不支持迭代器
数组可以看成一个容器,数组名就是迭代器
3.各容器常用函数
顺序容器和关联容器都有的函数:begin、end、rbegin、rend、erase、clear
3.1顺序容器函数
顺序容器都有的函数:front、back、push_back、pop_back、erase
vector函数
包含头文件#include<vector>
构造函数,初始化
vector();//容器初始化为空
vector(int n);//容器初始化为含n个元素
vector(int n,const T & val) ;//n个T类型的值为val的变量
vector(iterator fist,iterator last);//别的容器(数组)区间为[first,last)上的元素copy过来
vector<int> b(a) ; //声明并用向量a初始化向量b
常用函数
void pop_back();//删除容器末尾元素
void push_back(const T & val);//在容器末尾添加val
int size();//返回容器当前元素个数
bool empty();//判断容器是否为空
T & front();//返回容器第一个元素的引用
T & back();//返回容器最后一个元素的引用
其他一些函数示例
vector<int> v(5);
vector<int>::iterator i;
i=v.begin();//指向第一个元素
i=v.end();//指向最后一个元素的后一个
i=v.rbegin();//指向最后一个元素
i=v.rend();//指向第一个元素的前一个
v[1]=1;//v[i]表示对容器第i个元素索引
v.at(1)=1;//同v[i]
v.insert(v.begin()+2,1) ;//在begin()+2位置插入 1
v.insert(v.begin(), 3, 1000) ; //在begin()处连续插入3个1000
v.erase(v.begin()+1);//删除此迭代器位置的元素
v.erase(v.begin(),v.begin()+2);//删除[begin(),begin()+2)之间元素
v.clear(); //清空向量中的元素
v.remove(v.begin(), v.end(), 1); // 删除所有等于1的元素,但是容器大小不变
remove()只是将待删除元素之后的元素移动到vector的前端,而不是删除。若要真正移除,需要搭配使用erase()
vector<int> a,b;
a=b;//赋值
c1.swap(c2);//交换
swap(c1,c2);// 同上
vector构建二维动态数组
vector<vector<int>> v(3) ;//定义一个3行 不固定列的数组
//可以通过v[i].push_back(a)添加元素
//可以通过v[i][j]访问二维数组元素
deque函数
包含头文件#include<deque>
所有适用于vector的函数都适用于deque,除此之外,还有其他函数
deque<T> deq;
deq.push_front(const T & val);// 在队列前面添加元素
deq.pop_front();//删除头部的操作
list函数
包含头文件 #include<list>
除了具有所有顺序容器都有的函数: front、back、push_back、pop_back、erase、 begin、end、rbegin、rend、clear,还具有其他一些函数
list<T> lst,lst1;
lst.push_front(const T & val);//在链表前面添加元素
lst.pop_front();// 删除链表最前面的元素
list迭代器不支持随机访问,不能用STL中sort,有自己的sort函数
lst.sort(compare);//compare函数可以自己定义
lst.sort();//无参数默认从小到大
lst.remove(const T & val);//删除和val值相等的元素
lst.unique();//删除所有和前一个元素相同元素的元素
lst.merge(lst1);//合并两个链表,并清空被合并的链表(lst1),lst1内容放在lst之后,成为一个新的lst
lst.reverse();//颠倒链表
lst.swap(lst1);//将lst与lst1交换
list<T>::iterator p1,p2,p3;
lst.splice(p1,lst1,p2,p3);//在指定位置lst的p1前面插入另一链表lst1的[p2,p3)这段内容,并在另一个链表lst1中删除被插入[p2,p3)删除的元素
3.2关联容器函数
set/mutiset
包含头文件#include<set>
mutiset模板
template<class Key,class Pred=less<Key>,class A=allocator<Key> >
class mutiset{....};
//其中Pred决定了mutiset中元素的顺序是怎么定义的,默认为less,即从小到大,也可以通过重载()自己定义
//第三个参数一般不用考虑
mutiset函数
除了各容器都有的函数外,还支持以下成员函数:
iterator find(const T & val);//在容器中查找值为val的元素,返回其迭代器,找不到,则返回end();
iterator insert(iterator first,iterator last);//将区间[first,last) 插入容器
int count(const T & val)//在容器中统计有多少元素的值和val相等。
iterator lower_bound(const T & val);//查找一个最大的位置it,使得[begin(),it)中的所有元素比val小。
iterator upper_bound(const T & val);//查找一个最小的位置it,使得[it,end())中的所有元素比val大。
pair<itrator,iterator> equal_range(const T & val);//同时求得lower_bound,upper_bound。
set函数
set函数中与mutiset不同的是
pair<iterator,bool> insert(const T & val);//向容器中插入val
//当容器中没有与val元素相同的元素时,返回的first为当前插入的元素的迭代器,second为bool,false
//当容器中存在与val元素相同的元素时,返回的first为与插入的元素相同元素的迭代器,second为bool,ture
map/mutimap
包含头文件 #include<map>
mutimap模板
template<class Key, class T, class Pred=class<Key>, class A=allocator<T> >
class mutimap
{
typedef pair<const Key,T> value_type;
};
matimap中的元素由<关键字,值> 组成,每个元素是一个pair对象,first--Key,second--T
mutimap中元素排列顺序缺省情况下按照关键字的从小到大排列
pair模板
template<class T1,class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair():first(),second(){}
pair(const T1 & a,const T2 & b):first(a),second(b){}
template<class U1,class U2>
pair(const pair<U1,U2> & p):first(p.first),second(p.second){}
};
mutimap常用函数:
typedef mutimap<class Key,class T> Mmid;
Mmid a;
a.insert(Mmid::value_type(c,d));//插入一个pair
a.insert(make_pair(c,d)); //同上
a.count(Key e);//与键e相同的pair元素个数
Mmid::iterator i;
i->first;//Key的迭代器
i->second;//Value的迭代器
map函数
map与mutimap区别:map容器不允许同一元素pair(键相同的)出现两次,mutimap可以
函数基本与mutimap相同,不同的是map重载了[ ]
若pairs为map模板类对象
pairs[key];
返回对关键字等于key的元素的值(second成员变量) 的引用。相当于改变键为key对应的value
若没有关键字为key的元素,则会往pairs里插入一个关键字为key的元素,其值为构造函数初始化。一般为0
假设一开始pairs没有key=40的pair
int n=pairs[40]; //添加pair(40,0)
pair[40]=1; //将pair(40,0)改成(40,1)