1:STL初识
1.1 STL的诞生
STL 诞生来源
- 长久依赖,软件界一直希望建立一种可重复利用的东西
- C++ 的面向对象和泛型思想,目的就是复用性的提升
- 大多数情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复的工作
- 为了建立数据结构和算法的一套标准,于是就诞生了 STL
1.2 STL基本概念
1:STL(Standard Template Library 标准模板库)
2:STL从广义上分为:容器(container)算法(algorithm)迭代器(iterator)
3: 容器和算法之间通过迭代器进行进行无缝衔接
4:STL几乎所有代码都采用模板类或者模板函数
1.3 STL六大组件
STL分为六大组件,分别是:容器,算法,迭代器,仿函数,适配器(配接器),空间配置器
1:容器:各种数据结构 vector,list , deque,map等用来存放数据的
2:算法:各种常用算法 sort find copy for_each
3: 迭代器:扮演了容器和算法之间的胶合剂
4:仿函数:它的行为类似函数,可作为算法的某种策略
5: 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
6:空间配置器:负责空间的配置与管理
1.4 :STL中容器、算法、迭代器
容器:置物之所也
STL容器就是将运用最广泛的一些数据结构实现出来
常用数据结构:数组,链表,树,栈,队列,集合,映射等
算法:问题之间的解法
通过优限制的步骤,解决逻辑或者数学上的问题,这一门学科我们叫算法(Algorithms)
迭代器:容器和算法之间粘合剂
1:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式
2:每个容器都有自己的专属迭代器
3:迭代器使用类似于指针,初学阶段我们可以先理解迭代器为指针,将迭代器解引用口,就是模板参数列表中的数据类型
4:常用的容器中迭代器种类为双向迭代器和随机访问迭代器
2:初识容器,算法,迭代器
案例:STL中最常用的容器为 vector,可以理解为 数组,下面我们学习如何想这个容器中插入数据,并遍历这个容器。
#include<iostream>
#include<string>
#include<vector>
#include <algorithm>
using namespace std;
void MyPrint(int A) {
cout << A << endl;
}
void test() {
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
// 获取 iterator
vector<int>::iterator itBegin = v.begin();
vector<int>::iterator itEnd = v.end();
// 第一种方法:使用 while 循环
cout << "使用while循环遍历 vector" << endl;
while (itBegin != itEnd)
{
cout << *itBegin << endl;
itBegin++;
}
cout << "使用for循环遍历 vector" << endl;
// 第二种方法:使用for循环
for (vector<int>::iterator it = v.begin(); it !=v.end(); it++)
{
cout << *it << endl;
}
cout << "使用STL算法遍历 vector" << endl;
// 第三种方法:使用STL提供的标准便利算法(使用回调函数)
for_each(v.begin(), v.end(), MyPrint);
}
从运行结果可知:三种遍历方法均可遍历出 vector 内容。
我们解析下上面关于 vector 使用
1:vector是个模板,所以我们要通过模板参数指定容器中存放的数据类型,我们这里指定的是 int 类型
2:通过 vector 的成员函数 push_back 向容器中存放数据
3:每个容器都有自己的迭代器,迭代器用来遍历容器中的元素
------- -> v.begin() 返回迭代器,这个迭代器指向容器中的第一个数据
--------> v.end() 返回迭代器,这个迭代器指向容器中最后一个元素的下一个位置
--------》 vector<int>::iterator 拿到 vector<int> 这个容器的迭代器类型
4:通过拿到融国企的迭代器类型后,对迭代器解引用就可以得到容器中的数据,这样我们可以定义一个变量,用于接收在 v.begin()和 v.end()之前循环遍历容器中的元素
5:for_each() 算法定义如下:原理就是首尾之间的元素逐个传入指定的函数中
3:容器存放自定义数据类型
案例:我们定义一个 Person类,然后实例化一些对象,分别向2个vector 中插入对象和对象指针,然后遍历 vector并打印对象。
#include<iostream>
#include<string>
#include<vector>
#include <algorithm>
using namespace std;
class Person{
public:
Person(string name, int age) {
this->m_Age = age;
this->m_Name = name;
}
public:
string m_Name;
int m_Age;
};
void MyPrint(Person p) {
cout << p.m_Name << " " << p.m_Age << endl;
}
void test() {
// 定义Person类对象
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
vector<Person> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
// 获取 iterator
vector<Person>::iterator itBegin = v.begin();
vector<Person>::iterator itEnd = v.end();
// 第一种方法:使用 while 循环
cout << "使用while循环遍历 vector" << endl;
while (itBegin != itEnd)
{
cout << (*itBegin).m_Name <<" " << (*itBegin).m_Age<<endl;
itBegin++;
}
cout << "使用for循环遍历 vector" << endl;
// 第二种方法:使用for循环
for (vector<Person>::iterator it = v.begin(); it !=v.end(); it++)
{
cout << (*it).m_Name << " " << (*it).m_Age << endl;
}
cout << "使用STL算法遍历 vector" << endl;
// 第三种方法:使用STL提供的标准便利算法(使用回调函数)
for_each(v.begin(), v.end(), MyPrint);
}
int main() {
test();
}
4:容器嵌套容器
案例:容器中可以继续嵌套容器,比如我们在 vector中嵌套 vector ,就相当于一个二维数组,我们创建一个二维数组并将所有数据进行遍历输出。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void test() {
vector<vector<int>> v;
vector<int> v1;
vector<int> v2;
vector<int> v3;
vector<int> v4;
for (int i = 0; i < 4; i++)
{
v1.push_back(i + 1);
v2.push_back(i + 2);
v3.push_back(i + 3);
v4.push_back(i + 4);
}
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
v.push_back(v4);
for (vector<vector<int>>::iterator it = v.begin(); it < v.end(); it++)
{
// *it 就是 vector<int>
for (vector<int>::iterator vit = (*it).begin(); vit < (*it).end(); vit++)
{
cout << (*vit) << " ";
}
cout << endl;
}
}
int main() {
test();
}