C++ STL整理

一、迭代器

  • 迭代器:指针的抽象,也叫泛型指针
  • 迭代器是容器和算法之间的接口
  • 通过迭代器可以遍历容器中的序列,也可以遍历输入/输出流中的输入序列/输出序列。
  • 当两个迭代器对象指向同一容器中的同一元素 ,或当二者指向同一容器中最后一个元素的下一个位置时,两个迭代器相等。
迭代器的类别功能支持的操作备注
输入迭代器

*  ->  =  ++  ==  !=

输入迭代器的解引用操作的结果只能作为右值使用
输出迭代器*  ++  =输出迭代器的解引用操作的结果只能作为左值使用
正向迭代器读/写输入/输出迭代器支持的所有操作正向迭代器的解引用操作的结果即可作为左值又可作为右值使用。forward_list容器中的迭代器。
双向迭代器读/写正向迭代器支持的所有操作以及--STL容器提供的迭代器都至少达到双向迭代器的要求。
随机访问迭代器读/写双向迭代器支持的所有操作以及:两个迭代器之间的比较<  <=  >  >=,迭代器对象与整数n之间的+  +=  -  -=,两个迭代器相减-,下标操作[]当两个迭代器是同一容器中的迭代器时,比较操作才有意义;下标操作iter[n]==*(iter+n)
//distance();
template<typename InputIterator> 
typename iterator_traits<InputIterator>::difference_type distance (InputIterator first, InputIterator last);
//Return distance between iterators
//Calculates the number of elements between first and last

//advance()
template <typename InputIterator, typename Distance>
void advance (InputIterator& i, Distance n);
//Advances the iterator i by n elements.

二、容器

  • 容器:包含元素对象的对象。

2.1顺序容器

  • array
  • vector
  • deque(双端队列)
  • list(双链表)
  • forward_list(单链表)

2.1.1容器对象的定义及初始化

函数使用形式说明
C<T>c;创建空容器c
C<T>c(cx);

创建容器c作为cx的副本,c和cx必须是同类型且元素类型也相同的容器

C<T>c(b,e);创建容器c,并用迭代器[b,e)之内的元素的副本对c进行初始化
C<T>c(n,t);

创建容器c,并在其中存放n个值为t的元素,t必须是T类型的值,或者可以转换为T类型的值

C<T>c(n);

创建容器c,并在其中存放n个元素,每个元素都是T类型的值初始化元素

2.1.2容器中定义的类型别名

类型别名说明
iterator指向元素的迭代器的类型
const_iterator指向元素的常量迭代器的类型,只能读容器中的元素
reverse_iterator指向元素的逆向迭代器的类型,用于逆序寻址元素
const_reverse_iterator指向元素的常量逆序迭代器的类型,只能用于逆序读取容器中的元素
difference_type存储两个迭代器插值的有符号整型
value_type元素类型
reference元素的左值类型,等价于value_type&
const_reference元素的常量左值类型,等价于value_type&
size_type无符号整型,用于计算容器中的元素个数,也可用于对除list外的顺序容器进行检索

2.1.3访问元素

使用形式形式参数返回值备注
c.back()容器最后一个元素的引用若容器为空,则该操作的行为没有定义
c.front()容器第一个元素的引用若容器为空,则该操作的行为没有定义
c[index]index返回下标为index的元素的引用list容器无此操作;若下标越界,则该操作的行为没有定义
c.at(index)index返回下标为index的元素的引用

list容器无此操作;若下标越界,则该操作的行为没有定义

使用形式返回值备注
c.begin()迭代器指向容器c中的第一个元素此表的每一个操作都有两个版本,一个是const成员,一个是非const成员;若容器c为const对象,则这些操作返回的迭代器的类型是带const_前缀的类型(只读迭代器),否则返回读写迭代器
c.end()迭代器指向容器c中的最后一个元素的下一个位置
c.rbegin()逆向迭代器指向容器c中最后一个元素
c.rend()逆向迭代器指向容器中第一个元素的前一个位置

2.1.4增加元素

使用形式形式参数返回值操作效果
c.insert(iter,t)iter为迭代器,t为元素值指向新插入元素的迭代器在iter所指元素之前插入值为t的元素
c.insert(iter,n,t)iter为迭代器,t为元素值在iter所指元素之前插入n个值位t的元素
c.insert(iter,b,e)iter,b,e均为迭代器在iter所指元素之前插入[b,e)之内的元素
c.push_back(t)t为元素值在c的尾端增加值为t的元素
c.push_front(t)t为元素值

在c的头端增加值为t的元素

(注:vector没有push_front(t)用法)

2.1.5删除元素

使用形式形式参数返回值操作效果备注
c.clear()删除容器中的所有元素 
c.erase(iter)iter为迭代器迭代器指向被删除元素的下一元素删除iter所指向的元素若iter==c.end(),则该操作的行为没有定义
c.erase(b,e)b,e为迭代器迭代器指向被删除元素段的下一元素删除[b,e)之内的所有元素 
c.pop_back()删除容器中的最后一个元素若容器为空,则该操作的行为没有定义
c.pop_front()删除容器中的第一个元素

若容器为空,则该操作的行为没有定义

(注:vector没有push_front(t)用法)

2.1.6容器的比较

比较操作比较结果
==若两个容器中的元素个数相同且对应位置上的每个元素都相同,则比较结果为true,否则为false
!=与==相反
<  <=  >  >=

若一个容器中的所有元素与另一容器中头一段元素相等,则较短的容器小于另一容器;

否则,两个容器第一对不相等的比较结果就是容器的比较结果

2.1.7有关容器大小的操作

使用形式形式参数返回值操作效果
c.empty()

若容器为空,则返回true;

否则返回false

 
c.size()返回容器中目前所存放的元素的数目,类型为C::size_type 
c.max_size()返回容器中可存放元素的最大数目,类型为C::size_type 
c.resize()n为元素数目将容器重新调整为可存放n个元素;若n<c.size(),则删除多余元素,否则,在尾端增加相应数目的新元素,新元素均采用值初始化
c.resize(n,t)n为元素数目新增元素取值为t,其余同c.resize(n)

2.1.8容器的赋值与交换

使用形式形式参数操作效果备注
c1=c2c2为容器首先删除c1中的所有元素,然后将才中的元素复制给c1c1和c2必须是同类型容器且其元素类型也必须相同
c.assign(b,e)b,e为一对迭代器首先删除c中所有元素,然后将迭代器[b,e)之内的元素复制到c中b和e不能指向c中的元素,[b,e)之内的元素不必与c的元素类型相同,只需类型兼容即可
c.assign(n,t)n为元素数目,t为元素值首先删除c中的所有元素,然后在c中存放n个值为t的元素 
c.swap(c2)c2为容器交换c1和c2的所有元素c1和c2必须是同类型容器且其元素类型也必须相同

2.2有序关联容器

  • set
  • multiset
  • map
  • multimap

2.2.1pair类型
pair类型是一个模板类,在头文件utility中定义。一个pair对象包含两个公有数据成员:first和second。

创建pair对象的操作
使用形式说明
pair<T1,T2>p创建空的pair对象p,p的两个数据成员类型分别为T1,T2,均采用值初始化
pair<T1,T2>p(v1,v2)创建pair对象,p的两个数据成员的类型分别为T1,T2,成员first初始化为v1,成员second初始化为v2
make_pair(v1,v2)

标准库函数,使用值v1,v2创建pair对象

pair对象的比较操作
使用形式说明备注
p1<p2

若p1.first<p2.first或者!(p1.first<p2.first)&&p1.second<p2.second,则比较结果为true,否则为false

pair对象的比较使用其元素类型提供的相应比较操作
p1==p2若p1.first==p2.first&&p1.second==p2.second,则比较结果为true,否则为false

2.2.2map容器
map容器是键值对的集合,通常称为关联数组,通过键来访问值。所使用的键类型必须提供<操作符,若是类类型则要重载<操作符

map容器的构造函数
函数使用形式说明
map<K,T>m创建空的map容器m,其键类型为K,值类型为T
map<K,T>m(mx)创建map容器m作为mx的副本,m和mx的键值对类型必须相同
map<K,T>m(b,e)创建map容器,并用迭代器[b,e)范围之内的元素副本对m进行初始化
map类定义的类型别名
类型别名说明
key_type元素(pair对象)中键的类型
mapped_type元素中键所关联的值的类型
value_type元素的类型,是一个pair类型,其中first成员的类型为const map<K,T>::key_type,second成员的类型为map<K,T>::mapped_type

访问map容器中的元素,可以使用下标访问容器,下标是作为键使用,不一定要是整型,如果该元素存在,则返回元素中键所对应的值,如果指定的元素不存在,将会导致在容器中增加一个新元素,该元素的键值即为给定的下标值,元素的值采用值初始化。
注:map容器下标操作的返回值类型为mapped_type类型,容器的迭代器引用的返回值类型是value_type类型。

在map容器中增加元素
使用形式形式参数返回值操作效果
m.insert(e)e为元素值,一个pair对象一个pair对象,其first成员是指向被插入元素的迭代器,second成员是一个bool对象,表示是否插入了元素若键e.first不在容器m中,则插入元素e,否则m保持不变
m.insert(iter,e)iter为迭代器,表示搜索新元素存储位置的起点,e为元素值一个迭代器,指向键为e.first的元素在iter所指元素之后插入元素e,若键e.first已在容器m中,则m保持不变
m.insert(begin,end)begin,end均为迭代器,表示要插入的元素的范围将[begin,end)范围内的元素插入m中,若某元素的键已在m中,则不插入该元素
map容器的查找操作
使用形式形式参数返回值
m.find(k)k为要查找的键若容器m中存在与k对应的元素,则返回指向该元素的迭代器;否则返回指向m中最后一个元素的下一位置的迭代器
m.count(k)k为要查找的键k在容器m中出现的次数
从map容器中删除元素
使用形式形式参数返回值操作效果备注
m.erase(k)k为要删除元素的键被删除元素的个数,其类型为map容器中定义的size_type若容器m中存在键k的元素,则删除该元素若返回值为0,表示要删除的元素不存在
m.erase(iter)iter为指向要删除元素的迭代器删除iter所指向的元素若iter==m.end(),则该操作的行为没有定义
m.erase(b,e)b,e为迭代器删除[b,e)之内的元素要求b>=e,若b==e,则不删除任何元素;

其他函数:

  • max_size()

2.2.3multimap容器
与map容器的区别:
1)键可以重复,即可以有多个元素包含相同的键,因此multimap不支持下标操作
2)insert操作每调用一次都会增加新的元素,键相同的元素相邻存放
3)以键值为参数的erase操作删除该键所关联的第一个元素,并返回被删除元素的数目
4)count操作返回的迭代器指向被查找键相关联的第一个元素
5)find操作返回的迭代器指向与被查找键相关联的第一个元素

获取与指定键相关联的元素迭代器的操作
使用形式说明备注
m.lower_bound(k)返回一个迭代器,指向容器m中第一个键>=k的元素若键k不在容器中,则两个操作返回的迭代器相同:都指向k应该插入的位置
m.upper_bound(k)返回一个迭代器,指向容器m中第一个键<k的元素
m.equal_range(k)返回一对迭代器的pair对象,其中first==m.lower_bound(k),second==m.upper_bound(k) 

2.2.4set容器
特性:set容器中的元素就是键本身,set容器中的元素不能重复
与map容器的区别:
1)不支持下标操作
2)没有定义mapped_type类型
3)定义的value_type类型不是pair类型,而是与key_type相同

2.2.5multiset容器
与set容器的区别:键可以重复

2.3有序关联容器

  • unordered_set     //hast_set
  • unordered_multiset   //hash_multiset
  • unordered_map     //hash_map
  • unordered_multimap    //hash_multimap

2.4容器适配器

标准库容器适配器
类名说明所在头文件底层实现容器方法支持的操作符
stack堆栈,LIFO<stack>

deque(default)

list

vector

push(item)

pop()

top()

empty()

size()

每种容器都支持<  <=  >  >=  ==  !=,前提是元素类型要支持==和<操作。每两个适配器对象的比较由元素的依次比较而实现,结果取决于两个适配器中第一对不相等的元素。
queue队列,FIFO<queue>

deque(default)

list

push(item)

pop()

front()

back()

empty()

size()

priority_queue

优先级队列,元素按优先级从高到低排列,使用元素的<操作确定优先级

<queue>vector(default)见注4)

注:
1)每种适配器都定义了三种类型别名:

  • size_type表示适配器对象大小的类型
  • value_type元素类型
  • container_type基础容器的类型

2)每种适配器都定义了两个构造函数:

  • 不带参数的构造函数,用于创建空的适配器对象
  • 带一个容器参数的构造函数,用于根据基础容器内容创建适配器对象并进行初始化

3)priority_queue适配器支持的操作

  • push(item),按优先级顺序将值为item的新元素插入到队列中适当位置,无返回值。实现方式:首先调用基础容器的push_back操作,然后调用堆排序算法push_heap对元素进行重新排列
  • pop(),删除队首元素,无返回值。实现方式:首先调用堆操作算法pop_heap删除堆顶元素,然后调用基础容器的pop_back操作
  • top(),返回队首元素的值
  • empty()
  • size()

三、容器举例

3.1array
array是顺序容器的一种,跟数组很类似,array也是在栈上分配连续的内存,array的大小是不可改变的,定义array对象时就需要指明大小,所以只能修改array中的元素,不能向array中插入元素或从array中删除元素
3.1.1声明、初始化、赋值、交换

//第二个参数只能是整型常量,不能是变量
array<int, 10>arr1;   //定义一个array对象arr1,arr1中的元素是不确定的
arr1.fill(5);   //fill(value)方法可以将arr1的元素全赋值为相同的值value
array<int, 10>arr2 = { 0 };     //定义一个array对象arr2,arr2中的元素全为0,剩余的空位自动补零
array<int, 10>arr3 = { 1,2,3,4,5,6,7,8,9 };     //定义一个array对象arr3,arr3中的元素为1 2 3 4 5 6 7 8 9 0
array<int, 10>arr4 = arr2;  //array对象可以直接赋值,前提是两个对象的元素类型和个数相同
arr4 = arr3;    //legal
arr4 = { 1,2,3 };   //legal

swap(arr2, arr3);    //标准库方法
arr2.swap(arr3);    //array对象方法


3.1.2遍历

//跟数组一样遍历
for (int i = 0; i < arr.size(); i++)
{
    cout << arr[i] << " ";
    cout << arr.at(i) << " ";
} 
cout << endl;

//利用迭代器遍历
//array<int,10>::iterator it;
for (auto it = arr.begin(); it != arr.end(); it++)
    cout << *it << " ";
cout << endl;

//for-each遍历
for (auto i : arr)
    cout << i << " ";
cout << endl;

3.2vector

  • vector是顺序容器的一种,跟数组和array类似。vector是在堆上动态分配内存,大小可以自动调整。
  • 不会原地扩充,而是重新开辟一块两倍大的内存,然后把原先的元素拷贝到新的内存中。

3.2.1声明、初始化、赋值、交换

vector<int> vec1;   //定义一个空的vector对象vec1
//vec2/3/4是vec1的一个副本,若vec1.size()>vec2/3/4.size()则赋值后vec2/3/4.size()被扩充为vec1.size()
//前提是两个vector对象的元素类型要相同
vector<int>vec2(vec1);  //用vector对象初始化另一个vector对象
vector<int>vec3(vec1.begin(), vec1.end());  //用vector对象的部分元素初始化另一个vector对象
vector<int>vec4 = vec1; //将vector对象赋值给另一个vector对象
    
int length = 10;
vector<int> vec5(length);   //arr2包含length个0元素
vector<int> vec6(length, 3);    //temp中包含10个3
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
vector<int>vec7(arr,arr+10);    //可以将数组的部分连续元素的首尾地址传给vector对象

swap(arr1, arr2);
arr1.swap(arr2);

3.2.2遍历

//像数组一样遍历
for (int i = 0; i < vec.size(); i++)    //size()返回vec中的元素个数
{
    cout << vec[i] << " ";        //operator [],不做边界检查,可以越界,访问效率更高
    cout << vec.at(i) << " ";    //at(),访问越界会抛出异常,但访问效率不如[]
}
cout << endl;

//利用迭代器遍历
//vector<int>::iterator it;
for (auto it = vec.begin(); it != vec.end(); it++)
    cout << *it << " ";
cout << endl;

//for-each遍历
for (auto i : vec)
    cout << i << " ";
cout << endl;

3.2.3增加元素

  • vec.push_back(ele);

3.2.4删除元素

  • vec.pop_back();
  • vec.clear();     //清除整个vector
  • vec.erase(ite);    //清除迭代器ite指向的元素

3.2.5其他方法

  • empty()

3.3deque

3.4list

  • splice();
  •  

3.5forward_list

  • front()
  • push_front()
  • max_size()
  • sort()

3.5deque

  • push_back()
  • push_front()
  • size()
  • max_size()
  • front()
  • back()

3.6set

set的特性:set是关联容器,元素具有唯一性,而且有序

3.5.1.定义和声明
using namespace std;
set<int>s;

3.7multiset

  • insert()
  • max_size()
  • size()
  • find()

3.8map

同上

3.9unordered_set

  • bucket_count()
  • load_factor()
  • max_bucket_count()
  • max_load_factor()
  • bucket_size()
  • max_size()
  • find()

3.10unordered_map()

  • size()
  • max_size()
  • find()

四、算法

  • 算法使用迭代器在容器上进行操作。
  • 不修改序列的算法,在头文件algorithm中定义
  • 变更序列的算法,在头文件algorithm中定义
  • 排序及相关算法,在头文件algorithm中定义
  • 泛化算术算法,在头文件numeric中定义

五、仿函数

  • 仿函数:相当于函数指针
  • // TODO

六、分配器

// TODO

参考博客:
1.https://blog.csdn.net/SENLINZM/article/details/38682233

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值