Day 21 C ++ STL(Standard Template Library,标准模板库)

STL

  • 定义
  • STL六大组件
      • 容器——置物之所也
          • STL容器就是将运用最广泛的一些数据结构实现出来
          • 常用的数据结构
          • 序列式容器
          • 关联式容器
      • 算法——问题之解法也
          • 质变算法
          • 非质变算法
      • 迭代器——容器和算法之间粘合剂
          • 迭代器种类
          • 各种迭代器支持的常见运算操作
  • STL示例
      • 容器 —— `vector`
      • 迭代器: `vector<int>::iterator`
      • 算法—— `for_each`
      • 示例
      • 常用的算法函数
          • 排序算法:
          • 查找算法:
          • 合并算法:

定义

STL是C++中的一个重要组成部分。它的设计理念是提供一套通用、高效、可重用的数据结构和算法,并且尽量通过模板来实现泛化,以便满足各种不同的需求。

STL 从广义上分为: 容器(container) ,算法(algorithm) ,迭代器(iterator)

容器是用来存储数据的对象,可以看作是某种特定数据结构的封装。STL提供了多种不同类型的容器,如vector、list、map等,每种容器都有自己的特点和适用场景。

算法是对容器中数据进行操作的函数,比如查找、排序、删除等。STL提供了大量的算法,包括查找、排序、统计、遍历等等,可以方便地对容器中的元素进行各种处理。

迭代器是用于遍历容器中元素的对象,可以看作是一个指针。通过迭代器,可以按照线性顺序访问容器中的每个元素,从而实现对容器的操作。

STL的关键之处在于容器和算法之间通过迭代器进行无缝连接。算法并不依赖于具体的容器类型,而是通过迭代器来遍历和操作容器中的元素。这种设计使得算法可以复用于多种不同类型的容器,提高了代码的可重用性和灵活性。

STL的很多代码都采用了模板类或者模板函数的形式,这是为了实现泛化编程,即可以对不同的数据类型都适用。通过使用模板,STL可以根据不同的参数类型生成相应的代码,从而实现通用性和灵活性。

STL六大组件

STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器

  1. 容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
  2. 算法:各种常用的算法,如sort、find、copy、for_each等
  3. 迭代器:扮演了容器与算法之间的胶合剂。
  4. 仿函数行为类似函数,可作为算法的某种策略。
  5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
  6. 空间配置器:负责空间的配置与管理。

容器——置物之所也

STL容器就是将运用最广泛的一些数据结构实现出来

容器(Containers)用于存储和组织数据,并提供了对数据的访问和操作。常见的容器有vector、list、deque、set、map等。

常用的数据结构

数组, 链表,树, 栈, 队列, 集合, 映射表 等

这些容器分为序列式容器关联式容器两种

序列式容器

强调值的排序,序列式容器中的每个元素均有固定的位置

关联式容器

二叉树结构,各元素之间没有严格的物理上的顺序关系

算法——问题之解法也

有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms)
算法是对容器中的数据进行处理和操作的函数模板。STL提供了一系列算法,涵盖了各种常见的操作,如排序、查找、合并、复制等。

算法分为:质变算法非质变算法

质变算法

是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等

非质变算法

是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等

迭代器——容器和算法之间粘合剂

迭代器(Iterators)用于遍历容器中的元素。它提供了一种统一的访问容器中元素的方式,使得算法能够独立于容器而工作,能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。

每个容器都有自己专属的迭代器

迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针

常用的容器中迭代器种类为双向迭代器,和随机访问迭代器

迭代器种类
种类功能支持运算
输入迭代器对数据的只读访问只读,支持++、==、!=
输出迭代器对数据的只写访问只写,支持++
前向迭代器读写操作,并能向前推进迭代器读写,支持++、==、!=
双向迭代器读写操作,并能向前和向后操作读写,支持++、–,
随机访问迭代器读写操作,可以以跳跃的方式访问任意数据,功能最强的迭代器读写,支持++、–、[n]、-n、<、<=、>、>=
  1. 输入迭代器(Input Iterator):这种迭代器只能用于读取数据,它允许以顺序方式逐个访问元素,但不支持对元素进行写操作。例如,std::istream_iterator 是一个输入迭代器,用于从输入流中读取数据。
  2. 输出迭代器(Output Iterator):这种迭代器只能用于写入数据,它允许以顺序方式逐个写入元素,但不支持读取元素。例如,std::ostream_iterator 是一个输出迭代器,用于向输出流中写入数据。
  3. 前向迭代器(Forward Iterator):这种迭代器支持输入和输出操作,可以在集合中前后移动,并对元素进行读写操作,但只能遍历集合一次。例如,std::forward_liststd::unordered_set 的迭代器就属于前向迭代器。
  4. 双向迭代器(Bidirectional Iterator):这种迭代器比前向迭代器更强大,除了支持前向和后向移动外,还可以反向遍历集合。例如,std::liststd::set 的迭代器就属于双向迭代器。
  5. 随机访问迭代器(Random Access Iterator):这种迭代器提供了最强大的功能,除了支持前向、后向和随机移动外,还可以通过迭代器进行算术计算,实现跳跃式访问集合中的元素。例如,std::vectorstd::array 的迭代器就属于随机访问迭代器。

不同类型的迭代器支持的运算操作也略有不同。

各种迭代器支持的常见运算操作
  1. 输入迭代器(Input Iterator):支持以下操作:
    • *it获取迭代器指向的元素值
    • it++++it:将迭代器向前移动到下一个位置。
    • it == it2it != it2:比较两个迭代器是否相等或不相等。
  2. 输出迭代器(Output Iterator):支持以下操作:
    • *it = value:将值赋给迭代器指向的位置。
    • it++++it:将迭代器向前移动到下一个位置。
  3. 前向迭代器(Forward Iterator):除了支持输入迭代器和输出迭代器的所有操作之外,还支持以下操作:
    • it1 == it2it1 != it2:比较两个迭代器是否相等或不相等。
  4. 双向迭代器(Bidirectional Iterator):除了支持前向迭代器的所有操作之外,还支持以下操作:
    • it----it:将迭代器向后移动到前一个位置。
  5. 随机访问迭代器(Random Access Iterator):除了支持双向迭代器的所有操作之外,还支持以下操作:
    • it += nit -= n:将迭代器向前或向后移动 n 个位置。
    • it + nit - n:返回从迭代器开始向前或向后移动 n 个位置后的迭代器。
    • it1 - it2:计算两个迭代器之间的距离。
    • it[n]:返回迭代器指向的位置加上 n 的元素。

STL示例

容器 —— vector

创建vector容器对象,并且通过模板参数指定容器中存放的数据的类型:

vector<int>  v;

迭代器: vector<int>::iterator

每一个容器都有自己的迭代器,迭代器是用来遍历容器中的元素

v.begin() 返回迭代器,这个迭代器指向容器中第一个数据
v.end() 返回迭代器,这个迭代器指向容器元素的最后一个元素的下一个位置
vector<int>::iterator 拿到vector这种容器的迭代器类型

vector<int>::iterator it 创建迭代器对象

算法—— for_each

使用STL提供标准遍历算法 头文件 algorith

for_each 是C++算法库中的一个函数,用于对容器或范围内的元素逐个进行某种操作(函数)。

函数原型如下:

template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f);

参数说明:

  • firstlast:表示一个范围,指定需要进行操作的元素的起始和结束位置。
  • f:是一个一元函数对象(unary function),用于对元素进行操作。该函数对象接受一个元素作为参数,并返回结果(可选)。

for_each 函数会遍历指定范围内的每一个元素,将每个元素传递给函数对象 f 进行处理。

示例

#include <vector>
#include <algorithm>void MyPrint(int val)
{cout << val << endl;
}void test01() {//创建vector容器对象,并且通过模板参数指定容器中存放的数据的类型vector<int> v;//向容器中放数据v.push_back(10);v.push_back(20);v.push_back(30);v.push_back(40);//每一个容器都有自己的迭代器,迭代器是用来遍历容器中的元素//v.begin()返回迭代器,这个迭代器指向容器中第一个数据//v.end()返回迭代器,这个迭代器指向容器元素的最后一个元素的下一个位置//vector<int>::iterator 拿到vector<int>这种容器的迭代器类型vector<int>::iterator pBegin = v.begin();vector<int>::iterator pEnd = v.end();//第一种遍历方式:while (pBegin != pEnd) {cout << *pBegin << endl;pBegin++;}//第二种遍历方式:for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << endl;}cout << endl;//第三种遍历方式://使用STL提供标准遍历算法  头文件 algorithmfor_each(v.begin(), v.end(), MyPrint);
}int main() {test01();system("pause");return 0;
}

常用的算法函数

#include <algorithm> 是 C++ 中用于包含算法库的头文件。该头文件中包含了许多有用的算法函数,可以对容器、数组和其他数据结构进行各种操作,例如排序、查找、合并等。

使用 #include <algorithm> 可以使程序能够使用算法库中的函数。你可以根据需要选择适当的算法函数来处理数据,提高编程效率和代码可读性。

排序算法:
  • std::sort(first, last):对指定范围内的元素进行升序排序。
  • std::stable_sort(first, last):对指定范围内的元素进行稳定的升序排序。
查找算法:
  • std::find(first, last, value):在指定范围内查找第一个与给定值相等的元素,并返回其迭代器。
  • std::binary_search(first, last, value):在已排序的范围内使用二分查找算法查找指定值,返回是否找到。
合并算法:
  • std::merge(first1, last1, first2, last2, result):将两个已排序的范围归并成一个有序范围。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/24823.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 4G学习

硬件连接 ATK-IDM750C模块可直接与正点原子 MiniSTM32F103开发板板载的ATK模块接口&#xff08;ATK-MODULE&#xff09;进行连接。 功能说明 ATK-IDM750C是正点原子&#xff08;ALIENTEK&#xff09;团队开发的一款高性能4G Cat1 DTU产品&#xff0c;支持移动4G、联通4G和…

ChatGPT已闯入学术界,Elsevier推出AI工具

2022年11月&#xff0c;OpenAI公司发布了ChatGPT&#xff0c;这是迄今为止人工智能在现实世界中最重要的应用之一。 当前&#xff0c;互联网搜索引擎中出现了越来越多的人工智能&#xff08;AI&#xff09;聊天机器人&#xff0c;例如谷歌的Bard和微软的Bing&#xff0c;看起来…

深入理解Linux内核--系统调用

在应用程序和硬件间设置一个额外层优点&#xff1a; 1.使得编程更加容易 把用户从学习硬件设备的低级编程特性中解放出来 2.极大提高了系统的安全性 内核在试图满足某个请求前在接口级就可检查这种请求的正确性 3.接口使得程序更具有可移植性Unix系统通过向内核发出系统调用实现…

如何保证Redis缓存和数据库的一致性问题

熟练掌握Redis缓存技术&#xff1f; 那么请问Redis缓存中有几种读写策略&#xff0c;又是如何保证与数据库的一致性问题 今天来聊一聊常用的三种缓存读写策略 首先我们来思考一个问题 服务端到底是先更新db还是先更新cache 如果先更新缓存 写 先更新缓存再更新数据库 首先…

篇二:工厂方法模式:灵活创建对象

篇二&#xff1a;“工厂方法模式&#xff1a;灵活创建对象” 开始本篇文章之前先推荐一个好用的学习工具&#xff0c;AIRIght&#xff0c;借助于AI助手工具&#xff0c;学习事半功倍。欢迎访问&#xff1a;http://airight.fun/。 另外有2本不错的关于设计模式的资料&#xff…

Lombok 的安装与使用

文章目录 一、什么是 Lombok1.1 Lombok 的概念1.2 为什么使用 Lombok1.3 Lombok 的相关注解 二、Lombok 的安装2.1 引入依赖2.2 安装插件 三、Lombok 的使用案例四、Lombok 的原理 一、什么是 Lombok 1.1 Lombok 的概念 Lombok&#xff08;“Project Lombok”&#xff09;是一…

MySQL 窗口函数

聚合函数作为窗口函数 设聚合函数为op语法结构&#xff1a; op(字段名A) over(partition by 字段名B order by 字段名C rows between D1 and D2) 其中&#xff1a; partition by&#xff1a;按照某一字段将数据进行分组 order by&#xff1a;按照某一字段将数据进行排序&…

Java实现八皇后问题

八皇后问题说明 八皇后问题&#xff0c;是一个古老而著名的问题&#xff0c;是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯贝瑟尔于 1848 年提出&#xff1a;在 88 格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即&#xff1a;任意两个皇后都不…

HTTP常用状态码及其含义

HTTP常用状态码及其含义 1XX&#xff1a;信息&#xff0c;服务器收到请求&#xff0c;需要请求者继续执行操 状态码状态码英文名称中文描述100Continue继续。客户端应继续其请求101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议&…

筛选给定范围内的日志

目录 1.时间戳 2.实例 1.首先创建ubuntu.log日志 2.写dem.awk创建规则 3.筛选 1.时间戳 一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据,通常是一个字符序列&#xff0c;唯一地标识某一刻的时间。 awk提供了mktime()函数&#xff0c;它可以将时间…

31 对集合中的字符串,按照长度降序排列

思路&#xff1a;使用集合的sort方法&#xff0c;新建一个Comparator接口&#xff0c;泛型是<String>&#xff0c;重写里面的compare方法。 package jiang.com; import java.util.Arrays; import java.util.Comparator; import java.util.List;public class Practice4 {…

Spring Security 和 Apache Shiro 登录安全架构选型

Spring Security和Apache Shiro都是广泛使用的Java安全框架&#xff0c;它们都提供了许多功能来保护应用程序的安全性&#xff0c;包括身份验证、授权、加密、会话管理等。 Spring Security和Apache Shiro都是非常常用的登录安全框架,两者在登录安全架构的选型上各有特点: Sp…

WSL 2 installation is incomplete的解决方案

问题描述 解决方案 在Windows功能中开启Hyper-v 如果没有Hyper-v选项&#xff0c;新建文本粘贴以下内容后以.cmd为后缀保存后执行即可 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt for /f %%i in (findstr /i . hyper-v.t…

C语言进阶-3

1、程序为什么需要内存 1.1、计算机程序运行的目的 计算机为什么需要编程&#xff1f;编程已经编了很多年&#xff0c;已经写了很多程序&#xff0c;为什么还需要另外写程序&#xff1f;计算机有这个新的程序到底为了什么&#xff1f; 程序的目的是为了去运行&#xff0c;程序…

C++ 派生类的拷贝构造函数

当存在类的继承关系时&#xff0c;对于一个类&#xff0c;如果程序员没有编写拷贝构造函数&#xff0c;编译系统会在必要时自动生成一个隐含的拷贝构造函数&#xff0c;这个隐含的拷贝构造函数会自动调用基类的拷贝构造函数&#xff0c;然后对派生类新增的成员对象一一执行拷贝…

git merge 和rebase区别

Merge the incoming changes into the current branch 找到两个分支的祖先 commit&#xff0c;然后将公共分支最新版合并到自己的分支&#xff0c;形成一个新的 commit 提交&#xff0c;用图表示如下。 Rebase the current branch on top of the incoming Rebase 则是重新基于…

ubuntu samba 配置常见问题

samba配置&#xff1a; sudo vi /etc/samba/smb.conf [xxx 共享文件名] comment share folder browseable yes writable yes guest ok yes path /workdir/code/favarite create mask 0777 directory mask 0777 sudo /etc/init.d/smbd restart 重启smb服务 以上操作…

在服务器上搭建gitlab

最终效果展示&#xff1a; 官方文档&#xff1a; 安装部署GitLab服务 1.在服务器上下载gitlab wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-12.9.0-ce.0.el7.x86_64.rpm rpm -ivh gitlab-ce-12.9.0-ce.0.el7.x86_64.rpm 2.编辑站点位置 vim …

Kotlin 1.9.0 发布:带来多项新特性,改进 Multiplatform/Native 支持

新特性 Kotlin 的最新版本引入了许多新的语言特性&#xff0c;包括用于开放范围的…<操作符、扩展正则表达式等。此外&#xff0c;它还改进了 Kotlin Multiplatform 和 Kotlin/Native 支持。 Kotlin 1.9 稳定了与枚举类关联的 entries 属性&#xff0c;它会返回所定义的枚…

Spring Boot Logback日志格式改为JSON

在阿里云、或者日志分析时使用JSON格式输出日志更加方便。 依赖 增加Logbak JSON解析依赖。 另外需要注意的是JSON格式输出依赖Jackson&#xff0c;根据工程情况按需添加Jackson依赖。 <!--日志--><dependency><groupId>ch.qos.logback.contrib</grou…