第九层(1):初识STL
创始人
2024-05-16 16:46:56
0

文章目录

  • 前情回顾
  • 初识STL
    • STL的诞生
    • STL的基本概念
    • STL六大组件
    • STL中的容器、算法、迭代器
      • 容器
      • 算法
      • 迭代器
    • 容器、算法、迭代器的配合使用
    • vector中的嵌套使用
  • 石碑倒下...后面还有石碑?
  • 本章知识点(图片形式)

🎉welcome🎉
✒️博主介绍:一名大一的智能制造专业学生,在学习C/C++的路上会越走越远,后面不定期更新有关C/C++语法,数据结构,算法,Linux,ue5使用,制作游戏的心得,和大家一起共同成长。
✈️C++专栏:C++爬塔日记
😘博客制作不易,👍点赞+⭐收藏+➕关注

前情回顾

在上一层中,我见识到了C++中除了面向过程和面向对象之外的第三种编程方式——泛型编程,它可以大大提高代码复用性,主要靠模板去实现,在最后,石碑中说,学习模板不是为了写模板,而是为了更好的使用STL,STL是什么?我怀着疑问上到了第九层,抬头看到的是许久未见的天空…

  • 🚄上章地址:第八层:模板

初识STL

在我还在看天空的时候,一道声音把我从我自己的世界中拉了出来:“别看了,这层就是C++最后一层了,你已经到达塔顶了,这层的力量很强大,同时其中需要掌握的东西很多,我看好你…""顶层了,那你人在哪?我为什么看不到你?”我带着疑问,可是那道声音的主人没有回答我,我看着前面的石碑,心里有点失落,这么长时间的学习,马上就要结束了,心里感觉空落落的…

STL的诞生

  • 长久以来,在编程界中,一直希望建立一种可以重复利用的东西,而C++中的面向对象和泛型编程的主要目的就是提高代码的复用性,但是大多数情况下,数据结构和算法都未能有一套标志,每个人实现都有差异,但是实现内容是一样的,导致在项目中被迫从事了大量的重复工作,为了解决这种现象,就建立了数据结构和算法的一套标准,便是STL。

STL的基本概念

  • STL为标准的模板库,它所有的技术实现都利用到了模板技术,它从广义上讲分为了容器、算法、迭代器,其中,迭代器为连接容器和算法之间的桥梁

STL六大组件

  • STL分为容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
  • 容器:内部为各种数据结构,如vector、list、deque、set、map等,用来存放数据,所以为之容器
  • 算法:内部为各种的常用算法,如sort、find、copy、for_each等
  • 迭代器:扮演容器和算法之间的桥梁
  • 仿函数:行为类似函数,可作为算法的某种策略
  • 适配器:一种用来修饰容器或者仿函数或者迭代器接口的东西
  • 空间配置器:负责空间的配置和管理

在这里插入图片描述

STL中的容器、算法、迭代器

  • STL中的容器、算法、迭代器这三个每个又能分出几个小分支

容器

  • 容器可以分为两种:
  1. 序列式容器:强调值的排序,容器中每个元素都有固定的位置
  2. 关联式容器:二叉树结构,各元素没有严格的物理上的顺序
    在这里插入图片描述

算法

  • 算法同样分为两种:
  1. 质变算法:指运算过程中会更改区间内的元素内容,如:拷贝、替换、删除
  2. 非质变算法:运算过程中不会更改区间内元素的内容,如:查找、计数、寻找极值
    在这里插入图片描述

迭代器

  • 迭代器能依序的寻找某个容器中所含的各个元素,而不会暴露改容器的内部表示方法,每个容器都有属于自己的迭代器,同时可以把迭代器理解为指针,迭代器从种类分有五种:
种类功能支持运算
输入迭代器对数据只读支持++、==、!=
输出迭代器对数据只写支持++
前向迭代器可读可写,并能向前推进迭代器支持++、==、!=
双向迭代器可读可写,并能向前向后操作支持++、–
随机访问迭代器可读可写,可以以跳跃的方式访问数据支持++、–、[n]、-n、<、<=、>、>=
  • 最常用的迭代器为双向迭代器和随机访问迭代器

容器、算法、迭代器的配合使用

  • 上面说到迭代器是它们两个之间的桥梁,那应该怎么去搭配使用它们三个呢?在STL种最常用的容器为vector,可以理解为一个数组,那要怎么去使用这个容器放入数据呢?在使用这个容器之间,先引头文件:
  • #include< vector >
  • 创建方式:
    vector< 数据类型 > 变量名
  • 迭代器:
    vector< 数据类型 > :: iterator

那现在尝试写一个int类型的数组,用vector,并且设计出一种算法来打印它内部有的数据:

#include
#include
using namespace std;void test1()
{int i = 10;vector v;while (i--){v.push_back(i);//像v中上传数据}vector::iterator b = v.begin();//起始迭代器,指向容器中的第一个元素位置vector::iterator e = v.end();//结束迭代器,指向容器中最后一个元素加1的位置//第一种遍历方法while (b != e){//解引用操作找到迭代器指向的元素cout << *b << " ";b++;}cout << endl;
}
int main()
{test1();return 0;
}

在这里插入图片描述
第一种可以看到代码有点长,那有没有短一点的呢?

//第二种方法
void test1()
{int i = 10;vector v;while (i--){v.push_back(i);//像v中上传数据}for (vector::iterator b = v.begin(); b != v.end(); b++){cout << *b << " ";}cout << endl;
}
int main()
{test1();return 0;
}

在这里插入图片描述
可以替换成for循环,其实还有第三种方法,可以利用STL中提供的算法:

  • for_each( v.begin , v.end , 函数)

参数中的函数是for_each()在遍历期间会调用的,for_each()遍历的多少次,这个函数就会别调用多少次,同时使用这个算法需要引头文件

  • #include< algorithm >

现在可以试一下第三种方法:

#include
#include
#include
using namespace std;//用于for_each中的函数
void print(int a)//因为vector为int
{cout << a << " ";
}
void test1()
{int i = 10;vector v;while (i--){v.push_back(i);//像v中上传数据}//第三种方式for_each(v.begin(), v.end(), print);cout << endl;
}
int main()
{test1();return 0;
}

在这里插入图片描述
三种方法都可以使用,凭借个人喜好来选择。
那现在存放的是编译器的内置类型,可不可以用自定义类型呢?尝试一下:

#include
#include
#include
#include
using namespace std;//人类
class person
{
public:person(string a, int b){_name = a;_age = b;}string _name;int _age;
};
void print(person& p)
{cout << p._name << "的年龄为" << p._age << endl;
}
void test1()
{vector p;person p1("张三", 18);person p2("李四", 19);person p3("王五", 20);p.push_back(p1);p.push_back(p2);p.push_back(p3);//第一种方法vector::iterator b = p.begin();vector::iterator e = p.end();while (b != e){cout << b->_name << "的年龄为" << b->_age << endl;b++;}cout << endl;//第二种方法for (b = p.begin(); b != e; b++){cout << b->_name << "的年龄为" << b->_age << endl;}cout << endl;//d第三种方法for_each(p.begin(), p.end(), print);cout << endl;
}
int main()
{test1();return 0;
}

在这里插入图片描述
可以用自定义类型,并且三种方法都可以成功,同时这里也可以看到,把迭代器当作指针使用,是没有问题的。

vector中的嵌套使用

  • 上面说vector可以看做数组,那一个vector是个一维数组,那如果想用vector创建一个二维数组吗?如果可以怎么去创建?从二维数组去分析,二维数组的数组名代表了首元素地址,是第一个一维数组,那二维数组的本质就是一个数组里面嵌套了一堆数组,那vector是不是可以通过嵌套来实现一个二维数组?通过代码来验证一下:

现在创建一个int类型的二维数组:

#include
#include
#include
#include
using namespace std;void test1()
{vector> v;//创建大容器//创建小容器vector v1;vector v2;vector v3;vector v4;vector v5;//往小容器中写入数据for (int i = 0; i < 6; i++){v1.push_back(i);v2.push_back(i + 5);v3.push_back(i + 10);v4.push_back(i + 15);v5.push_back(i + 20);}//把小容器写入大容器v.push_back(v1);v.push_back(v2);v.push_back(v3);v.push_back(v4);v.push_back(v5);//通过大容器把小容器中的数都打印出来for (vector>::iterator b = v.begin(); b != v.end(); b++)//大容器的迭代器{for (vector::iterator b1 = (*b).begin(); b1 != (*b).end(); b1++)//要想遍历大容器的数据,要将所有小容器遍历一遍,小容器的迭代器{cout << *b1 << " ";}cout << endl;}
}
int main()
{test1();return 0;
}

在这里插入图片描述
是可以这样去使用的,可以用这样的方式去创建一个二维数组。

石碑倒下…后面还有石碑?

  • 当我掌握STL的基本使用的时候,面前的石碑倒下了,当我以为结束的时候,我看到后面还有一座石碑…

本章知识点(图片形式)

在这里插入图片描述

😘预知后事如何,关注新专栏,和我一起征服C++这座巨塔
🚀专栏:C++爬塔日记
🙉都看到这里了,留下你们的👍点赞+⭐收藏+📋评论吧🙉

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...