目录
1、stl概论和六大组件
2、STL三大组件
2.3.1 容器算法迭代器初识
3、常用容器
3.1.1 string 容器基本概念
3.2.1 简介
3.3.1 简介
目的:为了提高复用性。
1.1基本概念
STL(standard template Library,标准模板库)
STL从广义上分为:容器(container)算法(algorithm)迭代器(iterator)
1.2 六大组件简介
STL提供了六大组件,彼此之间可以相互套用:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
容器:各种数据结构,实现角度来看STL容器是一种class template;
算法:各种常用的算法,实现角度来看STL算法是一种function template;
迭代器:容器与算法的胶合剂,实现角度来看迭代器是一种将operator*、->、++、--等指针相关操作予以重载的class template,所有STL容器都附带有自己专属的迭代器,只有容器的设计者知道如何遍历自己的元素,原生指针(native pointer)也是一种迭代器;
仿函数:行为类似函数,可作为算法的某种策略。实现角度来看仿函数是一种重载operator()的class 或者 class template;
适配器(配接器):一种用来修饰容器或者仿函数或迭代器接口的东西;
空间配置器: 负责空间的配置与管理,实现角度来看配置器是一个实现了动态空间配置、空间管理、空间释放的class template。
交互关系: 容器通过空间配置器取得数据存储空间,算法通过迭代器存储容器中的内容,仿函数可以协助算法完成不同的策略的变化,适配器可以修饰仿函数。
1.3优点
STL是c++内置组件,不用安装额外的库;
STL的重要特性是数据与操作完全分离。数据由容器类别加以管理,操作则由可定制的算法定义;
熟练运用,不用了解底层;
高可重用性,高性能,高移植性,跨平台优点。几乎所有的戴拿都采用了模板类。
2.1 容器
常用的数据结构:array、list、tree、stack、queue、set、map,这些数据分为序列式容器和关联式容器两种。
序列式容器:有个固定的位置,出费用删除或插入的操作改变这个位置。
关联式容器:非线性存储结构,二叉树结构。在存入时没有保存逻辑顺序。
2.2算法
质变算法和非质变算法
质变算法:如插入、删除、排序等。
非质变算法:如查找、计数等。
2.3迭代器
依序寻访某个容器所含的各个元素。
迭代器种类
输入迭代器 |
数据只读 |
++、==、!= |
输出迭代器 |
数据只写 |
++ |
前向迭代器 |
读写,向前推进迭代器 |
++、==、!= |
双向迭代器 |
读写,双向推进迭代器 |
++、-- |
随机访问迭代器 |
读写,跳跃访问容器任意数据,功能最强迭代器 |
++、--、[n]、-n、<、<=、>、>= |
头文件 #include
声明变量 vector<类型> v
尾插 v.push_back(元素)
起始迭代器,v.begin(),指向第一个元素的地址
结束迭代器,v.end(),指向最后一个元素的下一个地址
遍历(三种)while、for、for_each()
#include
for_each(v.begin(),v.end(),迭代函数);
练习 内置数据类型、自定义数据类型、容器嵌套容器
---------------------------------------------------------20200125------------------------------------------------------
3.1 string 容器
string 管理*char所分配的内存,每一次string的赋值,取值都由string类负责维护,不用担心复制越界和取值越界等。
3.1.2.1 string构造函数
string();//创建一个空字符串
string(const string& str);//使用一个string对象初始化另一个string对象
string(const char *s);//使用字符串s初始化
string(int n,char c);//使用n个字符c初始化
3.1.2.2 string基本赋值操作
string& operator=(const char* s);//char*类型字符串赋值给当前字符串
string& operator=(const string &s);//char*类型字符串赋值给当前字符串
string& operator=(const char c);//字符赋值给当前字符串
string& assign(const char *s);//把字符串s赋给当前的字符串
string& assign(const char *s,int n);//把字符串s的前n个字符赋给当前的字符串
string& assign(const string &s);//把字符串s赋给当前的字符串
string& assign(int n, char c);//把n个字符c赋给当前的字符串
string& assign(const string &s, int start, int n);//将s 从 start开始n个字符赋给字符串
取值:at()和[]两种方式区别在于at()方法越界会抛出一个异常,[]程序会直接完犊子。
at()抛出的异常为out_of_range ,需要引入头文件stdexcept。
拼接、查找、替换: += 或append 进行拼接 find()进行查找,查不到返回-1;rfind()从右向左查。 Replace()替换
比较:compare() 相等为0, 大于则大于0 ,小于则小于0;
子串:substr(int pos=0,int n=npos)返回由pos开始的n个字符组成的字符串;
插入:insert()
删除: erase()
string类型和c_style类型(cahr *)字符串相互转化:
string -> c_style : const char *s=str.c_str();
c_style -> string : 使用字符串初始化即可;
编译器将const char* 可以 自动 隐式转换为string
反之,编译器不会将string 隐式类型转换为const char*
string 类型如果赋值长度发生变化,会导致内存的重新分配;
大写转换方法 toupper();
小写转换方法:tolower();
3.2 vector 容器
与数组类似但是是动态数组;
动态分配内存并不是原有空间分配,而是找一个新空间,将原有数据复制到新空间下,然后释放原有空间;
构造、赋值、交换
push_back();//尾插法
pop_back();//尾删法
v.begin()和v.end()返回值为指针,不是值;
v.begin()和v.end()是从右侧开始的;
v.capactity();//返回值为容器大小
size 容器元素的个数
empty 容器是否为空
resize 重新制定容器的长度,若比原来长,则用0填充;若比原来短,超出的部分删除掉;
reserve 预留空间,但是不初始化;
at 和 [] 同string
front 第一个元素
back 最后一个元素
insert(const_iterator pos,int count,ele) 插入的是一个迭代器,代表迭代器指向位置pos插入count个元素ele 插入
erase(迭代器) 删除
clear清空
-----------------------------------------20200127------------------------------------------------
巧用swap来收缩内存
vector
//未加粗部分是v和匿名的对象进行交换空间
巧用reserve预留空间
v.reserve(大小);
逆序遍历 :迭代器是reverse_iterator
随机访问 :迭代器 += 1;语法编译通过即可
3.3 deque容器
push_front();//头插法
pop_front();//头删法
push_back();//尾插法
pop_back();//尾删法
front();//头
back();//尾
begin();//头元素指针
end();//尾元素下一位置
//iterator 普通迭代器
//reverse_iterator 反转迭代器
//const_iterator 只读迭代器
----------------------------------20200128---------------------------------------------------