STL中的迭代器模式:将算法与数据结构分离
目录
1.概述
2.容器类
2.1.序列容器
2.2.关联容器
2.3.容器适配器
2.4.数组
3.迭代器
4.重用标准迭代器
5.总结
1.概述
在之前,我们讲了迭代器设计模式,分析了它的结构、角色以及优缺点:
设计模式之迭代器模式-CSDN博客
在 STL 中,算法通常作为函数模板来实现,而数据结构(容器)则是模板类。这种分离使得算法可以独立于特定的数据结构来编写和使用,只要数据结构满足算法所需的接口(例如迭代器接口)。
STL的中心思想是将算法与数据结构分离,彼此独立设计,最后在用iterator将他们结合在一起,获得最大的适配性。通过“迭代器”接口,已经实现了将算法与数据结构分离的目的。

2.容器类
容器类是STL非常重要的一部分,它们提供了用于存储、检索和操作数据对象(如整数、浮点数、字符串等)的模板类。以下是STL中一些主要的容器类:
2.1.序列容器
这些容器中的元素可以看作是线性排列的。
std::vector: 动态数组,可以动态地增加和减少元素。
std::deque: 双端队列,支持在序列的开头和结尾处快速插入和删除元素。
std::list: 双向链表,允许在任何位置进行快速插入和删除操作。
std::forward_list: 单向链表,仅支持向前迭代,并且在序列的开头进行快速插入和删除操作。
std::array: 固定大小的数组,不是动态的,但提供了更好的性能。
std::string: 特殊的动态字符数组,用于存储字符串。
std::stack: 后入先出(LIFO)的容器适配器,通常基于std::deque或std::vector实现。
std::queue: 先入先出(FIFO)的容器适配器,通常基于std::deque或std::list实现。
std::initializer_list: 初始化其它容器的容器,只是std::initializer_list不存储数据,详见:
C++之std::initializer_list详解_c++ std initializer-CSDN博客
2.2.关联容器
这些容器中的元素是按键(key)存储的,并且按键进行排序。
std::set: 集合,包含唯一的元素,按键排序。
std::multiset: 允许包含重复元素的集合。
std::map: 关联数组,其中每个元素都是一对键/值对,按键排序。
std::multimap: 允许键重复的关联数组。
std::unordered_set: 无序集合,包含唯一的元素,但不按键排序。
std::unordered_multiset: 允许包含重复元素的无序集合。
std::unordered_map: 无序关联数组,其中每个元素都是一对键/值对,但不按键排序。
std::unordered_multimap: 允许键重复的无序关联数组。
2.3.容器适配器
这些类不是容器本身,但它们为其他容器类提供了不同的接口。
std::stack: 后入先出(LIFO)的容器适配器。
std::queue: 先入先出(FIFO)的容器适配器。
std::priority_queue: 优先级队列,其中元素按优先级排序(通常基于堆实现)。
2.4.数组
对于C数组,指针扮演迭代器的角色。
int myInts[100];
std::for_each(myInts, myInts + 100, doSomething);
严格来说,myInts不是指针而是数组,但它仍然提供对数组的第一个元素的访问,而myInts + 100指向“结束后”的地址,符合begin-end的语义。
因此,C数组可以与算法一起使用,在旧代码中非常有帮助。
需要注意的是,自C++11以来引入了一种新的统一语法,使用std::begin(和std::end)自由函数(而不是类方法)。它们可以统一地用于任何具有可以无参数调用的begin(或end)方法的类型,并且也可以用于C数组。
下面的代码示例说明了这种统一性:
int myInts[100];
std::vector<int> vec(100, 0); // 大小为100且初始化为0std::for_each(std::begin(vec), std::end(vec), doSomething);
std::for_each(std::begin(myInts), std::end(myInts), doSomething);
这使得使用C数组变得更加简单,并且对于通用代码非常方便。
需要注意的是,对于C数组,必须显式地写出std命名空间,因为它无法使用ADL,但对于vector可以省略std命名空间。
3.迭代器
1) 上述序列容器和关联容器都提供了标准的迭代器操作:
正向迭代器:begin()和end()
反向迭代器:rbegin()和rend()
常量正向迭代器:cbegin()和cend()(或者const容器上的begin()和end())
常量反向迭代器:crbegin()和crend()(或者const容器上的rbegin()和rend())
2) 容器迭代器是不提供这些操作的。
3) 数组可以用std::begin()和std::end()来获取正向迭代器、反向迭代器、常量正向迭代器和常量反向迭代器。
4.重用标准迭代器
如果集合确实需要领域功能,或者只想要标准容器提供的部分功能,可能需要定义一个包装标准容器的类。在这种情况下,可以使用标准容器的迭代器来实现迭代器:
// 接口
class FlowCollection
{
public:// ...领域接口...// 允许访问数据的迭代器using const_iterator = std::vector<Flow>::const_iterator;const_iterator begin() const;const_iterator end() const;// 允许修改数据的迭代器using iterator = std::vector<Flow>::iterator;iterator begin();iterator end();// 其他迭代器...private:std::vector<Flow> m_flows;// ...领域数据...
};// 实现
FlowCollection::iterator FlowCollection::begin()
{return m_flows.begin();
}
那么算法就可以这样调用,以排序为例:
FlowCollection data;std::sort(data.begin(), data.end());
5.总结
STL 中的算法是一组函数模板,它们接受迭代器作为参数,并对迭代器范围内的元素执行操作。这些算法包括排序、搜索、复制、删除等操作。由于算法是独立于数据结构的,因此它们可以与任何支持迭代器接口的容器一起使用。
通过将算法与容器分离,STL 允许程序员根据需要组合不同的算法和容器。例如,你可以使用排序算法对向量进行排序,或者使用搜索算法在集合中查找元素。这种灵活性使得 STL 能够适应各种不同的应用场景。
总的来说,STL 的设计方式通过将算法与数据结构分离,实现了代码的可重用性、可维护性和灵活性。这使得 STL 成为 C++ 程序员在处理数据结构和算法时的重要工具。
相关文章:
STL中的迭代器模式:将算法与数据结构分离
目录 1.概述 2.容器类 2.1.序列容器 2.2.关联容器 2.3.容器适配器 2.4.数组 3.迭代器 4.重用标准迭代器 5.总结 1.概述 在之前,我们讲了迭代器设计模式,分析了它的结构、角色以及优缺点: 设计模式之迭代器模式-CSDN博客 在 STL 中&a…...
TCP、UDP详解
目录 1.区别 1.1 概括 1.2 详解 2.TCP 2.1 内容 2.2 可靠传输 2.2.1 确认应答 2.2.2 超时重传 2.2.3 连接管理 三次握手 四次挥手 2.2.4 滑动窗口 2.2.5 流量控制 2.2.6 拥塞控制 2.2.7 延时应答 2.2.8 捎带应答 2.2.9 面向字节流 2.2.10 异常情况的处理 1.…...
【脚本工具库】批量下采样图像(附源码)
在图像处理领域,我们经常需要对大批量图像进行下采样操作,以便减小图像的尺寸和文件大小,这对于节省存储空间和提高处理速度非常有帮助。手动操作不仅耗时,而且容易出错。为了解决这个问题,我们可以编写一个Python脚本…...
Web渗透:文件包含漏洞
Ⅱ.远程文件包含 远程文件包含漏洞(Remote File Inclusion, RFI)是一种Web应用程序漏洞,允许攻击者通过URL从远程服务器包含并执行文件;RFI漏洞通常出现在动态包含文件的功能中,且用户输入未经适当验证和过滤。接着我…...
什么是yum源?如何对其进行配置?
哈喽,大家好呀!这里是码农后端。今天来聊一聊Linux下的yum源及其配置相关的内容。简单来说,yum源就相当于一个管理软件的工具,可以想象成一个很大的仓库,里面存放着各种我们所需要的软件包及其依赖。 一、Linux下软件包…...
Node.js全栈指南:认识MIME和HTTP
MIME,全称 “多用途互联网邮件扩展类型”。 这名称相当学术,用人话来说就是: 我们浏览一个网页的时候,之所以能看到 html 文件展示成网页,图片可以正常显示,css 样式能正常影响网页效果,js 脚…...
基于weixin小程序智慧物业系统的设计
管理员账户功能包括:系统首页,个人中心,管理员管理,用户管理,员工管理,房屋管理,缴费管理,车位管理,报修管理 工作人员账号功能包括:系统首页,维…...
成功解决TypeError: __call__() got an unexpected keyword argument ‘first_int‘
成功解决TypeError: __call__() got an unexpected keyword argument first_int 目录 解决问题 解决思路 解决方法 T1、直接调用原始函数 T2、检查装饰器实现 T3、使用不同的调用方式 解决问题 result = multiply(**arguments) File "D:\ProgramData\Anaconda3\Li…...
vue3用自定义指令实现按钮权限
1,编写permission.ts文件 在src/utils/permission.ts import type { Directive } from "vue"; export const permission:Directive{// 在绑定元素的父组件被挂载后调用mounted(el,binding){// el:指令所绑定的元素,可以用来直接操…...
Nuxt3:当前页面滚动到指定位置
在Nuxt 3中,如果你想让当前页面跳转到指定位置,可以使用scrollIntoView方法。你需要给目标位置的元素添加一个ref引用,然后通过程序调用该ref来执行滚动。 以下是一个简单的例子: <template><div><!-- 其他内容 …...
word图题表题公式按照章节编号(不用题注)
预期效果: 其中3表示第三章,4表示第3章里的第4个图。标题、公式编号也是类似的。 为了达到这种按照章节编号的效果,原本可以用插入题注里的“包含章节编号” 但实际情况是,这不仅需要一级标题的序号是用“开始->多级列表”自动…...
最小生成树模型
文章目录 题单最小生成树模型1.[最短网络(prim)](https://www.acwing.com/problem/content/1142/)2. [局域网(kruskul)](https://www.acwing.com/problem/content/1143/)3. [繁忙的都市](https://www.acwing.com/problem/content/1144/)4. [ 联络员 ](https://www.acwing.com/p…...
基于盲信号处理的声音分离-基于改进的信息最大化的ICA算法
基于信息最大化的ICA算法的主要依据是使输入端与输出端的互信息达到最大,且输出各个分量之间的相关性最小化,即输出各个分量之间互信息量最小化,其算法的系统框图如图所示。 基于信息最大化的ICA算法的主要依据是使输入端与输出端的互信息达到…...
如何在Qt Designer中管理QSplitter
问题描述 当按下按钮时,我希望弹出一个对话框,用户可以在其中选择内容并最终按下 ‘Ok’ 按钮。我想在这个对话框中放置一个 QSplitter,左侧面板将显示树状结构,右侧将显示其他内容。如何正确实现这一点? 从 Qt 的示…...
关于新零售的一些思考
本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后,思考的重要性越来越高,后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售,本文是相关大量输入之后的思考,对新…...
C++初学者指南-2.输入和输出---从输入流错误中恢复
C初学者指南-2.输入和输出—从输入流错误中恢复 文章目录 C初学者指南-2.输入和输出---从输入流错误中恢复怎么了?解决方案:出错后重置输入流 怎么了? 示例:连续输入 int main () {cout << "i? ";int i 0;cin…...
毫秒级响应!清科优能应用 TDengine 建设虚拟电厂运营管理平台
小T导读:在清科优能的虚拟电厂运营管理平台建设中,项目初期预计涉及约一万台设备、总数据采集量达数十万,在数据库选择上,其希望能支持至少两千台设备的并发数据处理。本文介绍了清科优能的数据库选型经验以及最终应用效果&#x…...
【Ubuntu noble】apt 无法安装软件 Unable to locate package vim
宿主机以及 docker 无法定位软件包 将 /etc/apt/sources.list.d/ubuntu.sources 修改为以下内容(主要是 Suites 字段增加了noble noble-updates) Types: deb URIs: http://archive.ubuntu.com/ubuntu/ Suites: noble noble-updates noble-backports Com…...
Instagram APIj接口——快速获取Ins帖子媒体内容下载链接
一、引言 在社交媒体蓬勃发展的今天,Instagram已成为用户分享照片、视频和精彩瞬间的首选平台。然而,对于很多用户来说,想要保存或分享Instagram上的精彩内容却常常遇到困扰。为了解决这个问题,我们精心打造了一款全新的Instagra…...
Java基础(四)——字符串、StringBuffer、StringBuilder、StringJoiner
个人简介 👀个人主页: 前端杂货铺 ⚡开源项目: rich-vue3 (基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL) 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 …...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
