【C++泛型编程】(二)标准模板库 STL

文章目录

  • 标准模板库 STL
    • 容器
    • 算法
    • 迭代器
    • 仿函数/函数对象
    • 适配器
    • 分配器
    • 示例

标准模板库 STL

C++ 的标准模板库(Standard Template Library,STL)旨在通过模板化的设计,提供一种通用的编程模式,使程序员能方便地实现和扩展各种数据结构和算法,提高程序的开发效率和执行效率。STL 的设计遵循泛型编程的原则,其组件可以处理各种类型的数据。

STL 中的组件包括容器(containers)、迭代器(iterators)、算法(algorithms)、仿函数/函数对象(function objects)、适配器(adaptors) 和分配器(allocators)。他们的关系如图所示:

容器负责存储数据,算法用于执行数据处理操作,迭代器为算法提供数据访问机制,仿函数用于定义算法的行为策略,适配器用于修改和扩展接口,而分配器用于管理内存资源,

容器

容器是一组模板类,内部封装了数据的存储和访问机制,对外部提供了统一的接口。在STL中,容器被分为两大类:序列式容器(Sequence Containers)和关联式容器(Associative Containers)。

序列式容器用于存储具有严格线性关系的元素序列。它们以线性方式存储元素,可以动态地添加、删除和访问元素。序列式容器主要有以下几种:

  • std::vector:动态数组,可以存储相同类型的元素。支持随机访问元素,但在数组中间插入或删除元素可能会导致大量的元素移动。
  • std::deque:双端队列,具有在两端添加和删除元素的高效性。与std::vector类似,但支持更高效的头部插入和删除。
  • std::list:双向链表,元素在内存中不是连续存储的。在链表的任何位置添加或删除元素都非常高效,但随机访问元素效率较低。
  • std::forward_list(C++11起):单向链表,与std::list类似,但只支持向前迭代。
  • std::array(C++11起):固定大小的数组,不支持动态大小调整。提供与原生数组类似的性能,但具有STL容器的接口。
  • std::string:虽然std::string主要用于处理字符串,但它在内部实际上是一个特化的std::basic_string模板,因此也可以被视为一种序列式容器。

关联式容器存储的元素具有键值对(key-value pair)的关联关系。关联式容器内部通常使用红黑树(对于有序的容器)或哈希表(对于无序的容器)来实现,以支持高效的查找、插入和删除操作。关联式容器主要有以下几种:

  • std::set:集合,包含唯一的元素,元素在容器中按升序排列。
  • std::multiset:多重集合,允许存储重复的元素,元素在容器中按升序排列。
  • std::map:映射,存储键值对,其中键(key)是唯一的,并且按键的升序存储。
  • std::multimap:多重映射,允许存储具有相同键的多个键值对,并且按键的升序存储。
  • std::unordered_set(C++11起):无序集合,与std::set类似,但元素的顺序不保证。它使用哈希表来实现,因此插入、删除和查找操作的平均时间复杂度都是O(1)。
  • std::unordered_multiset(C++11起):无序多重集合,与std::multiset类似,但元素的顺序不保证。
  • std::unordered_map(C++11起):无序映射,与std::map类似,但元素的顺序不保证。它使用哈希表来实现,因此操作效率更高。
  • std::unordered_multimap(C++11起):无序多重映射,与std::multimap类似,但元素的顺序不保证。

算法

算法是处理数据的函数或函数模板,它们不存储数据,而是对数据进行操作。算法通过迭代器从容器中获取数据,并执行相应的操作。STL算法的头文件主要包括<algorithm><numeric><functional>。以下是一些常用的STL算法:

遍历算法

  • for_each:对容器中的每个元素执行指定的操作。

查找算法

  • find:在容器中查找等于指定值的元素。
  • find_if:在容器中查找满足特定条件的第一个元素。
  • adjacent_find:查找相邻的重复元素或满足特定条件的相邻元素对。
  • binary_search:在已排序的范围内查找指定元素。
  • count:计算容器中等于指定值的元素个数。
  • count_if:计算容器中满足特定条件的元素个数。

排序算法

  • sort:对容器中的元素进行排序。
  • random_shuffle:随机打乱容器中的元素顺序(注意:C++17开始已被弃用,推荐使用其他方式实现随机排序)。
  • merge:合并两个已排序的范围。
  • reverse:反转容器中的元素顺序。

拷贝和替换算法

  • copy:从一个位置拷贝元素到另一个位置。
  • replace:替换容器中等于指定值的元素。
  • replace_if:替换容器中满足特定条件的元素。
  • swap:交换两个元素的值。

算术生成算法

  • accumulate:计算容器中元素的累积和(或其他二元操作的累积结果)。
  • fill:用指定值填充容器中的元素。

集合算法

  • set_intersection:计算两个已排序集合的交集。
  • set_union:计算两个已排序集合的并集。
  • set_difference:计算两个已排序集合的差集(第一个集合中存在但第二个集合中不存在的元素)。

迭代器

迭代器是访问容器中元素的指针或类似指针的对象。 迭代器允许算法间接访问和操作容器中的元素。 容器可以通过返回迭代器的方式向算法暴露其内部元素。

仿函数/函数对象

仿函数/函数对象是一个行为类似于函数的对象,可以被调用,并且可以在泛型编程中用作函数参数,用于定义算法的行为策略 (允许我们为算法提供自定义的比较、判断或操作规则)。 在C++中,仿函数可以通过函数指针、函数对象(重载了函数调用运算符operator()的对象)、以及C++11引入的lambda表达式来定义。

适配器

适配器用于修改或扩展已有组件的接口,使它们能够更好地适应不同的使用场景。 STL中主要包括容器适配器,迭代器适配器和仿函数适配器。

容器适配器 提供了一种机制,用于修改或扩展容器的行为。STL提供了三种容器适配器:stack(栈)、queue(队列)和priority_queue(优先队列),其中stackqueue分别提供了栈和队列的数据结构,而priority_queue则允许元素根据优先级进行排序。

迭代器适配器(Iterator Adapters) 提供了一种机制,可以将非迭代器对象转换为迭代器对象,或者改变迭代器的行为。STL中的迭代器适配器包括back_insert_iteratorfront_insert_iteratorinsert_iterator等。这些适配器分别提供了在容器的末尾、开头或任意位置插入元素的功能。

函数对象适配器 STL中的函数函数适配器包括bindmem_funmem_fun_ref等。这些适配器可以将成员函数、函数指针或其他可调用对象转换为函数对象,以便与STL算法一起使用。

分配器

分配器在容器的创建和销毁过程中起着关键作用,它们负责为容器分配和回收内存资源。 STL容器默认使用标准分配器std::allocator,但也可以自定义分配器来满足特定的内存管理需求。

示例

下面是一个STL的使用示例,它使用了std::vector(容器)、迭代器、std::find_if(算法)、lambda函数(函数对象)、默认的std::allocator(隐式使用),以及std::stack(容器适配器):

#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>int main() {// 容器: 使用vector容器存储整数std::vector<int> numbers = {1, 5, 8, 3, 9, 2};// 迭代器: 使用迭代器(指针)遍历vector  // 1. 获取vector的begin()和end()迭代器  // 2. 使用迭代器 it 遍历容器中的元素,直到达到end()迭代器  for (std::vector<int>::iterator it = numbers .begin(); it != numbers .end(); ++it) {  std::cout << *it << " ";  } std::cout << std::endl;// 函数对象: 使用lambda表达式检查一个整数是否大于5auto is_greater_than_five = [](int num) { return num > 5; };// 算法: 使用find_if查找第一个大于5的数, it也为迭代器(指向结果的指针)auto it = std::find_if(numbers.begin(), numbers.end(), is_greater_than_five);if (it != numbers.end()) {std::cout << "Found a number greater than 5: " << *it << std::endl;} else {std::cout << "No number greater than 5 found." << std::endl;}// 容器适配器: 使用stack适配器(基于vector)std::stack<int, std::vector<int>> numStack;// 将vector中的元素压入stack中(这里为了演示,只压入找到的那个大于5的数)if (it != numbers.end()) {numStack.push(*it);}// 弹出stack中的元素并打印while (!numStack.empty()) {std::cout << "Popped from stack: " << numStack.top() << std::endl;numStack.pop();}// 分配器: vector默认使用std::allocator,而stack适配器也使用其底层容器的分配器return 0;
}
1 5 8 3 9 2 
Found a number greater than 5: 8
Popped from stack: 8

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

数据仓库项目---Day01

文章目录 框架的安装包数据仓库概念项目需求及架构设计项目需求分析项目框架技术选型系统数据流程设计框架版本选型集群资源规划设计 数据生成模块数据埋点主流埋点方式埋点数据上报时机 服务器和JDK准备搭建三台Linux虚拟机(VMWare)编写集群分发脚本xsyncSSH无密登录配置JDK准…

实现同一份数据的各种镜像

一个数据集通过某个轴&#xff08;通常是垂直或水平轴&#xff09;的镜像对称。这可以通过简单的数学运算来实现。 如果想要通过一块数据生成四份&#xff0c;可以通过以下步骤&#xff1a; 下面是一个简单的示例&#xff0c;展示了如何通过垂直轴&#xff08;左右对称&#…

找不到模块“vue-router”。你的意思是要将 moduleResolution 选项设置为 node,还是要将别名添加到 paths 选项中?

在tsconfig.app.json中添加&#xff0c;记得一定是 tsconfig.app.json 中&#xff0c;如添加到 tsconfig.node.json 还是会报错的 哈哈哈哈&#xff0c;不瞒你们&#xff0c;我就添加错了&#xff0c;哈哈哈。所以这也算写一个demo提醒自己 "compilerOptions": {&qu…

深入理解指针1

目录 如对您有帮助&#xff0c;还望三连支持&#xff0c;谢谢&#xff01;&#xff01;&#xff01; 1.内存和地址 计算机中常⻅的单位&#xff08;补充&#xff09;&#xff1a; 如何理解编址 2.指针变量和地址 2.1取地址操作符&#xff08;&&#xff09; 2.2指针变…

多个开源的js补环境框架测试

原文链接&#xff1a;https://mp.weixin.qq.com/s/uEMFGpE5bqmTvzSgX2twvA 前言 在做js逆向时肯定会遇到补环境的情况&#xff0c;看到github开源了好几个补环境用的框架&#xff0c;这篇文章做个测试&#xff0c;看看哪个比较好用。 https://github.com/pysunday/sdenvhttp…

Spring Boot3.x集成Disruptor4.0

Disruptor介绍 Disruptor是一个高性能内存队列&#xff0c;研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于Disruptor开发的系统单线程能支撑每秒600万订单&#xff0c;2010年在QCon演讲后&#xff0c;获得了业界关注。2011年&…

前端学习|第五章

HTML5&CSS3 新特性 前言HTML5 新特性一、语义化标签二、多媒体标签三、新增 input 类型四、新增表单属性 CSS3 新特性一、新增选择器二、盒子模型三、图片模糊处理四、calc 函数五、过渡 - transition六、2D 转换 - transform七、动画 - animation八、3D 转换 - translate3…

数据库被Elbie勒索病毒加密可以恢复吗?

一、Elbie勒索病毒简介 Elbie勒索病毒是一种严重的网络安全威胁&#xff0c;它通过加密用户文件并索要高额赎金来获取解密密钥。该病毒通常通过电子邮件附件、恶意网站、社交媒体平台以及利用用户网站服务器上的漏洞进行传播。一旦感染&#xff0c;用户的文件将被加密&#xff…

我独自升级崛起下载方法分享 下载教程

《我独自升级&#xff1a;崛起》这款精彩绝伦的动作角色扮演游戏&#xff0c;灵感来源于大热网络漫画&#xff0c;让玩家亲自踏上主角程肖宇的征途&#xff0c;从觉醒初阶到实力飞跃&#xff0c;每一步成长都扣人心弦。值得注意的是&#xff0c;尽管全球正式发布日期定在了五月…

RT-DETR-20240507周更说明|更新Inner-IoU、Focal-IoU、Focaler-IoU等数十种IoU计算方式

RT-DETR改进专栏|包含主干、模块、注意力、损失函数等改进 专栏介绍 本专栏包含模块、卷积、检测头、损失等深度学习前沿改进,目前已有改进点70&#xff01;每周更新。 20240507更新说明&#xff1a; ⭐⭐ 更新CIoU、DIoU、MDPIoU、GIoU、EIoU、SIoU、ShapeIou、PowerfulIoU、…

分析错误ValueError: could not determine the shape of object type ‘Series‘

这个错误提示 ValueError: could not determine the shape of object type Series 通常发生在尝试将 pandas 的 Series 直接转换为 PyTorch 的 tensor 时&#xff0c;尤其是当 Series 的数据类型不明确或者包含非数值类型的数据时。为了修正这个问题&#xff0c;确保在转换之前…

酷得智能电子方案 早教学习机

早教学习机是用户友好的&#xff0c;易于操作&#xff0c;同时要确保内容的科学性和适宜性&#xff0c;以促进儿童的健康成长和智力发展。 通常包括以下几个方面&#xff1a; 1.年龄分级内容&#xff1a;软件会根据儿童的不同年龄段提供相应的教育内容&#xff0c;从新生儿到…

FastDFS-单机扩容

描述 周一上班收到用户反馈系统异常&#xff0c;紧急排查日志发现报错&#xff1a;FdfsServerException:错误:28&#xff0c;错误信息:没有足够的存储空间。 解决 根据异常信息判断是文件服务器可用内存不够了&#xff0c;首先登录文件服务器&#xff0c;使用df -h命令查看一…

AIGC-3D数字人技术:高效助推各行业数字化水平升级

从“互联网”到“人工智能”&#xff0c;数字员工作为一种全新的交互形式&#xff0c;对企业有着重要的作用&#xff0c;企业、品牌通过数字人的AI语音交互、AI播报等核心功能&#xff0c;可以有效推动企业提升数字水平。 作为3D、AI虚拟数字人技术服务商及方案提供商&#xff…

Cargo - 构建 rust项目、管理依赖包

文章目录 关于 Cargo构建项目创建工程编译运行buildclean 管理依赖添加依赖updatecheck计时 manual rust 安装可参考&#xff1a;https://blog.csdn.net/lovechris00/article/details/124808034 关于 Cargo Cargo 官方文档 &#xff1a; https://doc.rust-lang.org/cargo/crat…

我写了一套几乎无敌的参数校验组件!基于 SpEL 的参数校验组件「SpEL Validator」

前言 大家好&#xff0c;我是阿杆&#xff0c;不是阿轩。 参数校验这个东西&#xff0c;很多情况下都是比较简单的&#xff0c;用 NotNull、Size 等注解就可以解决绝大多数场景&#xff0c;但也有一些场景是这些基本注解解决不了的&#xff0c;只能用一些其他的方式处理&…

OpenCV 入门(三)—— 车牌筛选

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

批量将GOID转成GO term名并添加BP,MF,CC分类信息

基因本体论&#xff08;Gene Ontology&#xff0c;GO&#xff0c;https://www.geneontology.org&#xff09;是一个广泛应用于生物信息学领域的知识库&#xff0c;它提供了一套标准化的词汇和分类体系&#xff0c;用于描述基因功能、细胞组分和生物过程。GO旨在统一科研人员对基…

LeetCode刷题记(五):121~150题

121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…

代码审计之某高校通用系统getRequsetURI函数的三次鉴权绕过

前言&#xff1a; 写个随笔&#xff0c;写个代码审计的漏洞案例&#xff0c;该系统为大量高校使用的一个系统。 三次绕过。 正文&#xff1a; 如图所见&#xff0c;系统厂商采用的是利用过滤器的写法进行鉴权 第一次的校验代码&#xff1a; 即requestURI转为小写后&#x…