STL(标准模板库)是一套 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。
C++ STL的核心包括三个组件:
容器(Containers) | 用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。 |
算法(Algorithms) | 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。 |
迭代器(iterators) | 迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。 |
三个组件都带有丰富的预定义函数,帮助我们通过简单的方式处理复杂的任务。
Vector是最常用的容器之一,是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组,因为其大小是根据实时更新而变化的。
vector的定义如下:
- Vector<类型> 标识符
- Vector<类型> 标识符(最大容量)
- Vector<类型> 标识符(最大容量,初始所有值)
- Vector<类型> v(i,i+2); //得到i索引值为3以后的值
- Vector< vector< int> >v; //二维向量,这里最外的<>要有空格。否则在比较旧的编译器下无法通过
例如:
- vector<int> v; // 储存int型的值
- vector<double> v; // 储存double型的值
- vector
v; // 储存string型的值 - vector<struct> v; // 储存结构体或者类的值的值
-
- /* 可以定义vector数组 */
- vector<int> a[n]; // 储存int型的值
- vector<double> a[n]; // 储存double型的值
容器特性:
- vector(); //创建一个空vector
- vector(int nSize); //创建一个vector,元素个数为nSize
- vector(int nSize,const t& t); //创建一个vector,元素个数为nSize,且值均为t
- vector(const vector&); //复制构造函数
- vector(begin,end); //复制[begin,end)区间内另一个数组的元素到vector中
- /* 向量尾部增加一个元素X */
- void push_back(const T& x);
- /* 向量中迭代器指向元素前增加一个元素x */
- iterator insert(iterator it,const T& x);
- /* 向量中迭代器指向元素前增加n个相同的元素x */
- iterator insert(iterator it,int n,const T& x);
- /* 向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据 */
- iterator insert(iterator it,const_iterator first,const_iterator last);
- iterator erase(iterator it); //删除向量中迭代器指向元素
- iterator erase(iterator first,iterator last); //删除向量中[first,last)中元素
- void pop_back(); //删除向量中最后一个元素
- void clear(); //清空向量中所有元素
-
- reference at(int pos); //返回pos位置元素的引用
- reference front(); //返回首元素的引用
- reference back(); //返回尾元素的引用
- iterator begin(); //返回向量头指针,指向第一个元素
- iterator end(); //返回向量尾指针,指向向量最后一个元素的下一个位置
- reverse_iterator rbegin(); //反向迭代器,指向最后一个元素
- reverse_iterator rend(); //反向迭代器,指向第一个元素之前的位置
bool empty() const; //判断向量是否为空,若为空,则向量中无元素
- int size() const; //返回向量中元素的个数
- int capacity() const; //返回当前向量所能容纳的最大元素值
- int max_size() const; //返回最大可允许的vector元素数量值
-
- /* 如果n小于当前容器的大小,则将内容减少到其前n个元素,并删除超出范围的元素(并销毁它们)*/
- void resize(size_type n);
-
- /**
- *如果n大于当前容器的大小,则通过在末尾插入所需数量的元素来扩展内容,以达到n的大小。
- *如果指定了val,则将新元素初始化为val的副本,否则将对它们进行值初始化。
- *如果n也大于当前容器容量,将自动重新分配已分配的存储空间
- */
- void resize(size_type n, const value_type& val);
-
- /**
- *表示预分配n个元素的存储空间,但不是真正的创建对象,
- *需要通过insert()或push_back()等操作创建对象。
- *调用reserve(n)后,若容器的capacity
- *若capacity>=n,capacity无变化。
- */
- void reserve(size_type n);
容器调用resize()函数后,所有的空间都已经初始化了,所以可以直接访问。而reserve()函数预分配出的空间没有被初始化,所以不可访问。区别:
下面用实例进行说明:
- #include
- #include
-
- using namespace std;
-
- int main(void)
- {
- vector<int> v;
- cout<<"v.size() == " << v.size() << " v.capacity() = " << v.capacity() << endl;
-
- v.reserve(10);
- cout<
5]<< endl; - cout<<"v.size() == " << v.size() << " v.capacity() = " << v.capacity() << endl;
-
- v.resize(10);
- v.push_back(0);
- cout<<"v.size() == " << v.size() << " v.capacity() = " << v.capacity() << endl;
-
- return 0;
- }
执行结果如下:
v.size() == 0 v.capacity() = 0
1735357008
v.size() == 0 v.capacity() = 10
v.size() == 11 v.capacity() = 20
注: 对于:v.reserve(10) 后接着直接使用 [ ] 访问越界报错(内存是野的),这里直接用[ ]访问,vector 退化为数组,不会进行越界的判断。此时推荐使用 at(),会先进行越界检查,如下所示:
cout<at(5)<< endl;
v.size() == 0 v.capacity() = 0
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 5) >= this->size() (which is 0)
相关引申:
针对 capacity 这个属性,STL 中的其他容器,如 list、 map、set、deque,由于这些容器的内存是散列分布的,因此不会发生类似 realloc() 的调用情况,因此可以认为 capacity 属性针对这些容器是没有意义的,因此设计时这些容器没有该属性。在 STL 中,拥有 capacity 属性的容器只有 vector 和 string。
这两个属性分别对应两个方法:resize() 和 reserve()。
- /* 交换两个同类型向量的数据 */
- void swap(vector&);
- /* 设置向量中前n个元素的值为x */
- void assign(int n,const T& x);//
- /* 向量中[first,last)中元素设置成当前向量元素 */
- void assign(const_iterator first,const_iterator last);
在容器最后移除和插入数据:
- #include
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- vector<int> obj; // 创建一个向量存储容器 int
- for(int i=0;i<10;i++) // 依次在数组最后添加数据
- {
- obj.push_back(i);
- cout<
"\t"; - }
-
- for(int j=0;j<5;j++) // 依次去掉数组最后一个数据
- {
- obj.pop_back();
- }
-
- cout<<"\n"<
-
- for(int k=0;k
size();k++) // size()返回容器中实际数据个数 - {
- cout<
"\t"; - }
-
- return 0;
- }
执行结果如下:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4
clear()
清除容器中所有数据:
- #include
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- vector<int> obj;
- for(int i=0;i<10;i++)
- {
- obj.push_back(i);
- cout<
"\t"; - }
-
- obj.clear();
- cout<
- for(int i=0;i
size();i++) - {
- cout<
"\t"; - }
- cout<
"size = "<size()<<", capacity = "<capacity(); -
- return 0;
- }
执行结果如下:
0 1 2 3 4 5 6 7 8 9
size = 0, capacity = 16
排序
sort() 函数需要包含头文件: #include
- #include
- #include
- #include
- #include
// 'sort()' and 'reverse()' was declared in this Header file -
- using namespace std;
-
- int main()
- {
- vector<int> obj;
-
- obj.push_back(1);
- obj.push_back(2);
- obj.push_back(3);
-
- cout<<"由小到大:"<
- sort(obj.begin(),obj.end());
- for(int i=0;i
size();i++) - {
- cout<
"\t"; - }
-
- cout<< endl <<"由大到小:"<
- reverse(obj.begin(),obj.end());
- for(int i=0;i
size();i++) - {
- cout<
"\t"; - }
-
- return 0;
- }
执行结果如下:
由小到大:
1 2 3
由大到小:
3 2 1
如果想 sort 来降序,可重写 sort
- /* 升序排列,如果改为return a>b,则为降序 */
- bool compare(int a,int b)
- {
- return a< b;
- }
-
- /* 示例 */
- int a[20]={2,4,1,23,5,76,0,43,24,65},i;
- for(i=0;i<20;i++)
- {
- cout<< a[i]<< endl;
- }
- sort(a,a+20,compare);
如下所示:
- #include
- #include
- #include
- #include
// 'sort' and 'reverse' was declared in this Header file -
- using namespace std;
-
- bool compare(int a,int b)
- {
- return a > b;
- }
-
- int main()
- {
- vector<int> obj;
-
- obj.push_back(1);
- obj.push_back(2);
- obj.push_back(3);
-
- cout<<"由小到大:"<
- sort(obj.begin(),obj.end());
- for(int i=0;i
size();i++) - {
- cout<
"\t"; - }
-
- cout<< endl <<"由大到小:"<
- sort(obj.begin(),obj.end(),compare); //sort 来降序
- for(int i=0;i
size();i++) - {
- cout<
"\t"; - }
-
- return 0;
- }
直接数组访问&迭代器访问
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- vector<int> obj;
- for(int i=0;i<10;i++)
- {
- obj.push_back(i);
- }
-
- // 方法一:直接数组访问
- cout<<"直接利用数组:"<<"\t";
- for(int i=0;i<10;i++)
- {
- cout<
"\t"; - }
-
- // 方法二:迭代器访问
- cout<
- cout<<"利用迭代器:"<<"\t";
- vector<int>::iterator it;
- for(it=obj.begin();it!=obj.end();it++)
- {
- cout<<*it<<"\t";
- }
-
- return 0;
- }
执行结果如下:
直接利用函数: 0 1 2 3 4 5 6 7 8 9
利用迭代器: 0 1 2 3 4 5 6 7 8 9
二维数组两种定义方法
假设定义一个二维数组obj[5][6],两种定义方法的结果一样:
方法一
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- int N=5,M=6; // 定义二维动态数组大小5行为5行6列,值默认全为0
- vector< vector<int> > obj(N); // 开辟行
- for(int i=0;i
size();i++) - {
- obj[i].resize(M); // 开辟行
- }
-
- for(int i=0;i
size();i++) // 赋值,并输出二维动态数组 - {
- for(int j=0;j
size();j++) - {
- obj[i][j]=i+j;
- cout<
"\t"; - }
- cout<
- }
-
- return 0;
- }
方法二
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- int N=5,M=6; // 定义二维动态数组大小5行为5行6列,值默认全为0
-
- /* 创建一个vector,元素个数为N,且值均为一个元素个数为M的vector
(M) */ - vector< vector<int> > obj(N,vector<int>(M));
-
- for(int i=0;i
size();i++) // 赋值,并输出二维动态数组 - {
- for(int j=0;j
size();j++) - {
- obj[i][j]=i+j;
- cout<
"\t"; - }
- cout<
- }
-
- return 0;
- }
输出结果为:
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
标准库
C++ 标准库可以分为两部分:
- 标准函数库: 由通用的、独立的、不属于任何类的函数组成的。它继承自 C 语言。
- 面向对象类库: 这个库是类及其相关函数的集合。
C++ 标准库包含了所有的 C 标准库,为了支持类型安全,做了一定的添加和修改。
标准函数库
标准函数库分为以下几类:
- 输入/输出 I/O
- 字符串和字符处理
- 数学
- 时间、日期和本地化
- 动态分配
- 其他
- 宽字符函数
面向对象类库
面向对象类库定义了大量支持一些常见操作的类,比如输入/输出 I/O、字符串处理、数值处理。面向对象类库包含以下内容:
- 标准的 C++ I/O 类
- String 类
- 数值类
- STL 容器类
- STL 算法
- STL 函数对象
- STL 迭代器
- STL 分配器
- 本地化库
- 异常处理类
- 杂项支持库
-
相关阅读:
局部线性嵌入(Locally Linear Embedding, LLE)
Electron打包Vue踩坑记录
【软件工程】四、编码 & 维护
python 基础语法 (常常容易漏掉)
R实现动态条件相关模型与GARCH模型结合研究中美股市动态相关性(DCC-GARCH模型)
java毕业设计超市购物数据管理系统mybatis+源码+调试部署+系统+数据库+lw
网络安全笔记 -- 文件操作(文件下载读取)
valgrind,memcheck的使用
Nmap使用教程图文教程(超详细)
redis的常用基础类型及操作
-
原文地址:https://blog.csdn.net/weixin_60461563/article/details/132859978