原学习链接:https://blog.csdn.net/acceptedday/article/details/118529280
C++ STL
C++的面向对象和泛型编程思想,目的就是复用性的提升
大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作。为了建立数据结构和算法的一套标准,诞生了STL
基本概念
- STL(Standard Template Library,标准模板库)
- STL 从广义上分为: 容器(container) 算法(algorithm) 迭代器(iterator)
- 容器和算法之间通过迭代器进行无缝连接。
- STL 几乎所有的代码都采用了模板类或者模板函数
六大组件
- 容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
- 算法:各种常用的算法,如sort、find、copy、for_each等
- 迭代器:扮演了容器与算法之间的胶合剂。
- 仿函数:行为类似函数,可作为算法的某种策略。
- 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
- 空间配置器:负责空间的配置与管理。
示例:vector
容器: vector 算法: for_each 迭代器: vector<int>::iterator
1. string
本质:
- string是C++风格的字符串,而string本质上是一个类
string和char * 区别:
- char * 是一个指针
- string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。
string构造函数
string();
string(const char* s);
string(const string& str);
string(int n, char c);
string赋值操作
string& operator=(const char* s);
string& operator=(const string &s);
string& operator=(char c);
string& assign(const char *s);
string& assign(const char *s, int n);
string& assign(const string &s);
string& assign(int n, char c);
string的赋值方式很多, operator= 这种方式是比较实用的
string字符串拼接
string& operator+=(const char* str);
string& operator+=(const char c);
string& operator+=(const string& str);
string& append(const char *s);
string& append(const char *s, int n);
string& append(const string &s);
string& append(const string &s, int pos, int n);
string查找和替换
int find(const string& str, int pos = 0) const;
int find(const char* s, int pos = 0) const;
int find(const char* s, int pos, int n) const;
int find(const char c, int pos = 0) const;
int rfind(const string& str, int pos = npos) const;
int rfind(const char* s, int pos = npos) const;
int rfind(const char* s, int pos, int n) const;
int rfind(const char c, int pos = 0) const;
string& replace(int pos, int n, const string& str);
string& replace(int pos, int n,const char* s);
注意:
- find查找是从左往后,rfind从右往左
- find找到字符串后返回查找的第一个字符位置,找不到返回-1
- replace在替换时,要指定从哪个位置起,多少个字符,替换成什么样的字符串
string字符串比较
字符串比较是按字符的ASCII码进行对比
返回 0 = 返回 1 > 返回 -1 <
int compare(const string &s) const;
int compare(const char *s) const;
string字符存取
char& operator[](int n);
char& at(int n);
string插入和删除
string& insert(int pos, const char* s);
string& insert(int pos, const string& str);
string& insert(int pos, int n, char c);
string& erase(int pos, int n = npos);
string子串
string substr(int pos = 0, int n = npos) const;
2. vector容器
vector数据结构和数组非常相似,也称为单端数组
vector与普通数组区别:数组是静态空间,而vector可以动态扩展(并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间)
vector构造函数
vector<T> v;
vector(v.begin(), v.end());
vector(n, elem);
vector(const vector &vec);
vector赋值操作
vector& operator=(const vector &vec);
assign(beg, end);
assign(n, elem);
vector容量和大小
empty();
capacity();
size();
resize(int num);
resize(int num, elem);
vector插入和删除
push_back(ele);
pop_back();
insert(const_iterator pos, ele);
insert(const_iterator pos, int count,ele);
erase(const_iterator pos);
erase(const_iterator start, const_iterator end);
clear();
vector数据存取
at(int idx);
operator[];
front();
back();
vector互换容器
swap(vec);
vector预留空间
减少vector在动态扩展容量时的扩展次数
reserve(int len);
3. deque容器
双端数组,可以对头端进行插入删除操作
deque与vector区别
- vector对于头部的插入删除效率低,数据量越大,效率越低
- deque相对而言,对头部的插入删除速度回比vector快
- vector访问元素时的速度会比deque快,这和两者内部实现有关
deque构造函数
deque<T> deqT;
deque(beg, end);
deque(n, elem);
deque(const deque &deq);
deque赋值操作
deque& operator=(const deque &deq);
assign(beg, end);
assign(n, elem);
deque大小操作
deque.empty();
deque.size();
deque.resize(num);
deque.resize(num, elem);
deque 插入和删除
两端插入操作:
push_back(elem);
push_front(elem);
pop_back();
pop_front();
指定位置操作:
insert(pos,elem);
insert(pos,n,elem);
insert(pos,beg,end);
clear();
erase(beg,end);
erase(pos);
deque 数据存取
at(int idx);
operator[];
front();
back();
deque 排序
sort(iterator beg, iterator end)
4. stack容器
stack是一种先进后出(First In Last Out,FILO)的数据结构,只有一个出口
构造函数
stack<T> stk;
stack(const stack &stk);
赋值操作
stack& operator=(const stack &stk);
数据存取
push(elem);
pop();
top();
大小操作
empty();
size();
5. queue容器
Queue是一种先进先出(First In First Out,FIFO)的数据结构,有两个出口
构造函数
queue<T> que;
queue(const queue &que);
赋值操作
queue& operator=(const queue &que);
数据存取
push(elem);
pop();
back();
front();
大小操作
empty();
size();
6. list容器
功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
list的优点:
- 采用动态存储分配,不会造成内存浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
- 链表灵活,但是空间(指针域) 和 时间(遍历)额外耗费较大
List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
list构造函数
list<T> lst;
list(beg,end);
list(n,elem);
list(const list &lst);
list 赋值和交换
assign(beg, end);
assign(n, elem);
list& operator=(const list &lst);
swap(lst);
list 大小操作
size();
empty();
resize(num);
resize(num, elem);
list 插入和删除
push_back(elem);
pop_back();
push_front(elem);
pop_front();
insert(pos,elem);
insert(pos,n,elem);
insert(pos,beg,end);
clear();
erase(beg,end);
erase(pos);
remove(elem);
list 数据存取
front();
back();
list 反转和排序
reverse();
sort();
7. set/ multiset 容器
所有元素都会在插入时自动被排序
set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
set构造和赋值
set<T> st;
set(const set &st);
set& operator=(const set &st);
set大小和交换
size();
empty();
swap(st);
set插入和删除
insert(elem);
clear();
erase(pos);
erase(beg, end);
erase(elem);
set查找和统计
find(key);
count(key);
pair对组创建
成对出现的数据,利用对组可以返回两个数据。
pair<type, type> p(value1, value2);
pair<type, type> p = make_pair( value1, value2 );
set容器排序
8. map/ multimap容器
map中所有元素都是pair pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值) 所有元素都会根据元素的键值自动排序
map/multimap属于关联式容器,底层结构是用二叉树实现。
map和multimap区别
- map不允许容器中有重复key值元素
- multimap允许容器中有重复key值元素
map构造和赋值
map<T1, T2> mp;
map(const map &mp);
map& operator=(const map &mp);
map大小和交换
size();
empty();
swap(st);
map插入和删除
insert(elem);
clear();
erase(pos);
erase(beg, end);
erase(key);
map查找和统计
find(key);
count(key);
map容器排序
STL-常用算法
算法主要是由头文件<algorithm> <functional> <numeric> 组成。
<algorithm> 是所有STL头文件中最大的一个,范围涉及到比较、 交换、查找、遍历操作、复制、修改等等 <numeric> 体积很小,只包括几个在序列上面进行简单数学运算的模板函数 <functional> 定义了一些模板类,用以声明函数对象。
1. 遍历算法
for_each
实现遍历容器
for_each(iterator beg, iterator end, _func);
for_each在实际开发中是最常用遍历算法,需要熟练掌握
transform
搬运容器到另一个容器中
transform(iterator beg1, iterator end1, iterator beg2, _func);
搬运的目标容器必须要提前开辟空间,否则无法正常搬运
2. 查找算法
find
查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
find(iterator beg, iterator end, value);
find_if
按条件查找元素
find_if(iterator beg, iterator end, _Pred);
find_if按条件查找使查找更加灵活,提供的仿函数可以改变不同的策略
adjacent_find
查找相邻重复元素
adjacent_find(iterator beg, iterator end);
binary_search
查找指定元素是否存在
bool binary_search(iterator beg, iterator end, value);
count
统计元素个数
count(iterator beg, iterator end, value);
统计自定义数据类型时候,需要配合重载 operator==
count_if
按条件统计元素个数
count_if(iterator beg, iterator end, _Pred);
按值统计用count,按条件统计用count_if
3. 排序算法
sort
对容器内元素进行排序
sort(iterator beg, iterator end, _Pred);
sort属于开发中最常用的算法之一,需熟练掌握
random_shuffle
洗牌 指定范围内的元素随机调整次序
random_shuffle(iterator beg, iterator end);
配合随机种子:srand((unsigned int)time(NULL)); 使用
merge
两个容器元素合并,并存储到另一容器中
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
注意: 两个容器必须是有序的
reverse
将容器内元素进行反转
reverse(iterator beg, iterator end);
4. 拷贝和替换算法
copy
容器内指定范围的元素拷贝到另一容器中
copy(iterator beg, iterator end, iterator dest);
replace
将容器内指定范围的旧元素修改为新元素
replace(iterator beg, iterator end, oldvalue, newvalue);
replace_if
将区间内满足条件的元素,替换成指定元素
replace_if(iterator beg, iterator end, _pred, newvalue);
replace_if按条件查找,可以利用仿函数灵活筛选满足的条件
swap
互换两个容器的元素
swap(container c1, container c2);
5. 算术生成算法
计算区间内 容器元素累计总和
accumulate
accumulate(iterator beg, iterator end, value);
accumulate使用时头文件注意是 numeric
fill
向容器中填充指定的元素
fill(iterator beg, iterator end, value);
6. 集合算法
set_intersection
求两个容器的交集
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
注意:
- 求交集的两个集合必须的有序序列
- 目标容器开辟空间需要从两个容器中取小值
- set_intersection返回值是交集中最后一个元素的位置
set_union
求两个集合的并集
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
注意:
- 求并集的两个集合必须的有序序列
- 目标容器开辟空间需要两个容器相加
- set_union返回值是并集中最后一个元素的位置
set_difference
求两个集合的差集
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
注意:
- 求差集的两个集合必须的有序序列
- 目标容器开辟空间需要从两个容器取较大值
- set_difference返回值是差集中最后一个元素的位置
|