标准模板库STL
标准模板库 不是面向对象编程,而是泛型编程。
容器
创建
- 使用动态内存分配
- 所有STL容器都接受一个可选的模板参数,该参数指定用哪个分配器对象来管理内存。默认使用allocator < T >类,这个类使用new和delete。
template <class T,class Allocator = allocator<T> >
class vector{...}
遍历容器元素的三种方式
- for循环
- for_each( )函数
- 基于范围的for循环
vector<Review>::iterator pr;
for(pr = books.begin();pr != books.end(); pr++)
{...}
for_each(books.begin(),books.end();func_name);
for(auto x : books) func_name(x);
容器的通用操作
- size( ) : 容器中元素数目
- swap( ) : 交换两个容器的内容
- begin( ) : 指向容器第一个元素的迭代器
- end( ) : 指向超过容器尾的迭代器
- cbegin( ) : 指向容器第一个元素的const迭代器
- cend( ) : 指向超过容器尾的const迭代器
- vector< int >::iterator, vector< int >:: value_type, ==, !=
序列容器
序列中的元素就有特定的顺序
序列容器的通用操作
- X a(n,t), X(n,t):构造函数,n个类型为t的值
- X a(i,j), X(i,j):构造函数,i和j表示两个迭代器
- a.insert(p,t),a.insert(p,n,t),a.insert(p,i,j)将t插入到p前面,p为迭代器
- a.erase(p),a.erase(p,q)
- a.clear()
序列容器的可选操作
vector、list、deque:
- a.front():返回首元素的值
- a.back():返回最后一个元素的值
- a.push_back(t)
- a.pop_back(t)
list、deque:
- a.push_front()
- a.pop_front()
vector、deque:
- a[n]
- a.at[n]:会执行边界检查
array固定长度的数组
vector长度可变的数组
- 自动内存管理
- 可反转容器:rbegin(),rend()
deque双端队列
- 与vector的区别是从开始位置插入和删除元素的时间是固定的
list双向链表
- 可反转容器,不可随机访问
- 与vector的区别,从容器删除或者插入元素之后,链表迭代器指向元素将不变
- list成员函数
void merge(list<T,Alloc>& x);//将链表x与调用链表合并,两个链表必须已经排序,之后x为空,线性时间
void remove(const T & val);//删除调用链表中的所有实例val,线性时间
void sort();//从小到大排序,NlogN
void splice(iterator pos, list<T,Alloc> x);//将链表x中的内容插入到pos前面,x将为空,固定时间
void unique();//将连续的相同元素进行压缩,线性时间
forward_list单向链表(C++11)
- 不可反转容器,只需要正向迭代器
stack栈
- 适配器类,底层为vector
- 允许的操作:size( ), empty( ), top( ), pop( ), push( )
queue先进先出队列
- 适配器类,让底层类(通常为deque)展示典型的队列接口
- 不允许随机访问队列元素,甚至不允许遍历队列
- 可允许的操作:删除队首元素pop( ); 查看队首元素front( ); 查看队尾元素 back( );将元素添加到队尾 push( ); 检查元素数目 size( ); 测试队列是否空empty( );
priority_queue
- 在< queue >中声明,适配器类,默认的底层类是vector
- 支持的操作与queue相同,但是最大的元素被移到队首
- 可以通过提供一个可选的构造函数参数修改用于确定哪个元素放到队首的比较方式
priori_queue<int> q1(greater<int>);
关联容器
将值与键关联在一起,使用键查找值,可以实现快速查找。通常底层是用树实现的。X::value_type值类型 ,X::key_type键类型。
set
值和键相同,不能有相同的键,可反转,经过排序
常用方法:
set<string> A(s1,s1+N);//构造函数
set_union(s1.begin(),s1.end(),s2.begin(),s2.end(),iterator1);//两个集合的并集,最后一个参数表示要复制到什么位置
set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),iterator1);//两个集合的交集
set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),iterator1);//集合是s1的元素减去集合s1和集合s2共有的元素
A.insert("sdf");//插入无法指定位置
copy(A.lower_bound("sdf"),C.upper_bound("iio"),iterator1);//lower_bound()第一个不小于这个键的元素,upper_bound()第一个大于这个键的元素
multiset
值和键相同,可以有相同的键
map
值和键不同,键是唯一的,每个键对应一个值
multimap
值和键不同,键是唯一的,一个键可以对应多个值,可反转,经过排序;
实际的值类型将键类型和数据类型结合为一对,pair< class T,class U>
常用方法:
typedef pair<const int,string> Pair;
multimap<int, string> Mapcode;
Mapcode code;
code.insert(Pair(312,"San Francisco"));
code.count(312);
pair<Mapcode::iterator,Mapcode::iterator> range = codes.equal_range(312);//返回两个迭代器,表示键对应的值的区间,封装在一个pair里
Mapcode::iterator it;
for(it = range.first;it!=range.second;++it)
cout<<(*it).second<<endl;
无序关联容器
底层是基于哈希表的,旨在提高添加、删除、查找算法的效率;