std : : vector

一.简介

std::vector 的底层实现通常基于动态数组(dynamic array),它是一种连续分配的内存块,允许元素的快速随机访问。下面是 std::vector 的一些关键特点和底层实现细节:

  1. 连续内存块std::vector 内部使用一块连续的内存块来存储其元素,这使得元素的随机访问非常高效,因为可以通过指针算术运算来访问元素。

  2. 动态大小std::vector 允许动态地增加或减少其大小。当元素数量达到内部分配的容量时,std::vector 会重新分配更大的内存块,并将元素复制到新的内存块中。这种自动内存管理使得向量的大小可以根据需要进行调整,而不需要手动管理内存。

  3. 容量和大小std::vector 有两个重要的属性,即容量(capacity)和大小(size)。

    • 容量是 std::vector 当前内部分配的内存块的大小,通常大于或等于大小。当向量的大小超过容量时,会触发内存重新分配,容量会增加。
    • 大小是 std::vector 中实际存储的元素数量。
  4. 动态内存分配std::vector 使用 newdelete 运算符(或 mallocfree 函数,取决于具体实现)来动态分配和释放内存。当需要重新分配内存时,它会为新的内存块分配内存,然后将元素从旧的内存块复制到新的内存块,最后释放旧内存。

  5. 异常安全std::vector 的实现通常会提供异常安全性,这意味着如果在内存重新分配过程中发生异常,不会导致数据丢失或内存泄漏。这是通过使用临时副本和交换技术来实现的。

  6. 迭代器std::vector 提供了迭代器(iterator)来遍历元素,迭代器通常是指针的封装,可以用于访问 std::vector 中的元素。

  7. 内存效率:由于 std::vector 的元素存储在连续的内存块中,它在内存访问上具有很好的局部性,这有助于提高内存访问效率。

总之,std::vector 是一个非常灵活和高效的容器,它提供了动态数组的功能,使得元素的访问和管理变得非常方便。虽然 std::vector 的大小可以动态增长,但由于内存重新分配的开销,如果需要频繁插入或删除元素,可能需要考虑其他容器类型,如 std::liststd::deque,它们可以更高效地支持插入和删除操作。

扩展:

动态数组(Dynamic Array)是一种数据结构,它是一个连续分配的内存块,用于存储具有相同数据类型的元素。动态数组的大小可以动态增长或缩小,以适应元素的插入和删除操作。

以下是动态数组的主要特点和操作:

  1. 连续内存块:动态数组的元素存储在一块连续的内存块中,这意味着元素的地址在内存中是连续的,这有助于快速随机访问元素。通过索引访问元素的时间复杂度是 O(1)。

  2. 动态大小:动态数组允许在运行时动态增加或减少其大小。这意味着您可以向数组中添加元素或从数组中删除元素,而不需要预先知道数组的大小。这种动态大小的特性使得动态数组非常灵活。

  3. 内存分配:当向动态数组添加元素并且没有足够的内存容量时,动态数组会自动分配更大的内存块,将现有元素复制到新的内存块中,并释放旧的内存块。这个过程称为重新分配(re-allocation)。

  4. 时间复杂度:动态数组的插入和删除操作的时间复杂度取决于插入或删除的位置。在末尾进行插入和删除操作通常是最高效的,时间复杂度为 O(1),因为不需要移动元素。在数组中间进行插入或删除操作可能需要移动后续元素,时间复杂度为 O(n)。

  5. 容量和大小:动态数组具有容量(capacity)和大小(size)两个重要属性。

    • 容量是动态数组内部分配的内存块的大小,通常大于或等于大小。
    • 大小是动态数组中实际存储的元素数量。
  6. 迭代器:动态数组通常提供迭代器(iterator),可以用于遍历数组中的元素。

动态数组是一种非常常见和有用的数据结构,它具有灵活性和高效性的优点。

二.运用场景

std::vector 是 C++ 标准库提供的一个动态数组容器,它在许多不同的场景中都非常有用。以下是一些常见的 std::vector 的运用场景:

  1. 动态数组std::vector 是一种动态数组,它可以根据需要自动增加或减少大小。这使得它成为存储不确定数量元素的首选选择,而不需要预先知道数组的大小

  2. 数据收集std::vector 适用于收集大量数据,例如从文件、网络或用户输入中读取的数据。您可以使用 push_back() 方法轻松添加新数据。

  3. 容器替代std::vector 可以替代 C 数组,因为它提供了更多的功能和安全性。与 C 数组不同,std::vector 知道自己的大小,而且可以动态调整大小。

  4. 迭代访问:如果需要通过索引或迭代器访问元素,并且需要快速随机访问能力std::vector 是一个很好的选择。它的时间复杂度为 O(1)。

  5. 栈和队列:虽然 std::vector 主要设计用于随机访问,但它也可以用作栈(先进后出)或队列(先进先出)。使用 push_back()pop_back() 方法可以将其用作栈,而使用 push_back()erase() 可以将其用作队列。

  6. 算法和数据处理std::vector 与标准库中的各种算法结合使用,可以用于各种数据处理任务,例如排序、查找、筛选、转换等。

  7. 高性能计算:在需要高性能的数值计算领域,std::vector 通常用于存储大量数值数据,例如图形处理、科学计算、模拟等。

  8. 游戏开发:在游戏开发中,std::vector 常用于存储游戏对象、粒子、动画帧等

  9. 数据传输std::vector 可以用于数据传输,例如从文件读取数据到向量,然后将向量传递给其他处理模块。

需要注意的是,虽然 std::vector 在许多情况下非常有用,但在某些特定情况下,其他容器类型(例如 std::liststd::dequestd::setstd::map 等)可能更适合特定的数据结构和操作。因此,在选择容器类型时,需要根据具体的需求和性能要求进行权衡和选择。

三.写个比较器

方法一:直接静态函数
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
static bool cmp(const pair<int, int>& a, const pair<int, int>& b) {if (a.first == b.first) return a.second < b.second;return a.first < b.first;
}
void display(vector<pair<int,int>>ans) { for (auto it : ans) cout << it.first << " " << it.second<<"\t"; }
int main() {vector<pair<int, int>>ans = { {1,2},{5,3},{2,5},{2,1},{7,2} };display(ans);cout << endl;sort(ans.begin(), ans .end(), cmp);display(ans);return 0;
}

 

方法二:写入结构体
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct cmp {bool operator()(const pair<int,int>&a,const pair<int,int>&b) {if (a.first == b.first) return a.second < b.second;return a.first < b.first;}
};
void display(vector<pair<int,int>>ans) { for (auto it : ans) cout << it.first << " " << it.second<<"\t"; }
int main() {vector<pair<int, int>>ans = { {1,2},{5,3},{2,5},{2,1},{7,2} };display(ans);sort(ans.begin(), ans .end(), cmp());cout << "----------" << endl;display(ans);return 0;
}

         在使用的时候,cmp() 表示实例化对象,要是不想实例化对象怎么办呢?这个时候我们可以把比较操作定义成静态成员函数,这样就可以通过这个结构体的名称来调用这个函数,而不需要实例化对象。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct numcmp {static bool cmp(const pair<int, int>& a, const pair<int, int>& b) {if (a.first == b.first) return a.second < b.second;return a.first < b.first;}
};
void display(vector<pair<int,int>>ans) { for (auto it : ans) cout << it.first << " " << it.second<<"\t"; }
int main() {vector<pair<int, int>>ans = { {1,2},{5,3},{2,5},{2,1},{7,2} };display(ans);cout << endl;sort(ans.begin(), ans .end(), numcmp::cmp);display(ans);return 0;
}

 

区别:

这两种写法在功能上是等效的,它们都可以用于自定义比较操作,以对pair或其他数据结构进行排序。然而,它们之间有一些细微的区别和优劣势:

  1. 可读性:使用函数指针或函数对象(结构体中的operator())来定义比较操作,通常更易于理解和阅读。函数名可以明确指示比较的目的,而不需要查看结构体的成员。

  2. 灵活性:将比较操作封装在结构体中(函数对象方式)通常更灵活,因为你可以在结构体中存储额外的状态或配置,以影响比较的行为。这对于实现不同的排序方式很有用。

  3. 命名冲突:如果你有多个不同的比较操作,并且它们需要在不同的上下文中使用,将它们放入结构体中可以避免函数名冲突的问题,因为每个结构体都有自己的作用域。函数指针方式可能需要更多的命名空间管理。

  4. 语法:函数指针方式更紧凑,但在语法上可能略显繁琐。函数对象方式需要创建一个结构体并在排序函数中使用括号运算符来调用,这可能看起来有点冗长。

总的来说,选择哪种方式取决于你的需求和个人偏好。如果你只需要一个简单的比较操作,函数指针可能更合适。但如果你需要更复杂的比较逻辑,或者希望更好地组织和封装比较操作,那么使用函数对象(结构体中的operator())可能更好。

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

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

相关文章

MAC M1芯片安装mounty读写移动硬盘中的文件

因为移动硬盘中的文件是微软公司NTFS格式&#xff0c;MAC只支持自己的APFS或者HFS&#xff0c;与微软的NTFS不兼容&#xff0c;所以需要第三方的软件来支持读写硬盘中的文件&#xff0c;经过一上午的折腾&#xff0c;最终选择安装mounty这个免费的第三方软件 工具网址连接&am…

祝贺!Databend Cloud 入驻 AWS 云市场

关于 Databend Cloud Databend Cloud 是基于开源云原生数仓项目 Databend 打造的一款易用、低成本、高性能的新一代大数据分析平台&#xff0c;提供一站式 SaaS 服务&#xff0c;免运维、开箱即用。 Databend Cloud 架构如下&#xff1a; 存储层完全面向对象存储而设计。 计算…

[论文笔记]BiMPM

引言 这又是一篇文本匹配的论文Bilateral Multi-Perspective Matching for Natural Language Sentences阅读笔记。 论文题目为自然语言文本中双向多视角匹配。 提出了BiMPM(bilateral multi-perspective matching)模型: 基于匹配-聚合(比较-聚合)框架; 采用双向匹配提取交…

第25节-PhotoShop基础课程-文本工具组

文章目录 前言1.横排文字工具1.基本操作1.字体选择2.字体大小3.字体颜色4.左对齐5.右对齐6.居中对齐 2.字符 2.段落文字3.蒙版文字 前言 1.横排文字工具 1.基本操作 1.字体选择 2.字体大小 3.字体颜色 4.左对齐 5.右对齐 6.居中对齐 2.字符 2.段落文字 3.蒙版文字

如何正确使用 WEB 接口的 HTTP 状态码和业务状态码?

当设计和开发 Web 接口时&#xff0c;必然会和 HTTP 状态码与业务状态码这两个概念打交道。很多同学可能没有注意过这两个概念或者两者的区别&#xff0c;做得稀里糊涂&#xff0c;接下来详细讲解下二者的定义、区别和使用方法。 HTTP 状态码 HTTP 状态码是由 HTTP 协议定义的…

Stable Diffusion 告别猜关键词,LoRA适配关键词自动生成

有没有想想过在SD绘图的时候下载好的LoRA模型选择之后不生效是为什么?或者说关键词不知道怎么填写? 这里介绍基于 Civitai 的LoRA 使用方法。 文章目录 Civitai 插件使用方法Civitai 插件 如果没有安装的小伙伴可以参考前面的文章先对 Civitai 的模型管理进行安装和使用,确…

【iOS】MVC

文章目录 前言一、MVC各层职责1.1、controller层1.2、model层1.3、view层 二、总结三、优缺点3.1、优点3.2、缺点 四、代码示例 前言 MVC模式的目的是实现一种动态的程序设计&#xff0c;使后续对程序的修改和扩展简化&#xff0c;并且使程序某一部分的重复利用成为可能。除此…

【python爬虫】批量识别pdf中的英文,自动翻译成中文上

不管是上学还是上班,有时不可避免需要看英文文章,特别是在写毕业论文的时候。比较头疼的是把专业性很强的英文pdf文章翻译成中文。我记得我上学的时候,是一段一段复制,或者碰到不认识的单词就百度翻译一下,非常耗费时间。本文提供批量识别pdf中英文的方法,后续文章实现自…

CnosDB 签约京清能源,助力分布式光伏发电解决监测系统难题。

近日&#xff0c;京清能源采购CnosDB&#xff0c;升级其“太阳能光伏电站一体化监控平台”。该平台可以实现电站设备统一运行监控&#xff0c;数据集中管理&#xff0c;为操作人员、维护人员、管理人员提供全面、便捷、差异化的数据和服务。 京清能源集团有限公司&#xff08;…

【新版】系统架构设计师 - 软件架构设计<SOA与微服务>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 架构 - 软件架构设计&#xff1c;SOA与微服务&#xff1e; 考点摘要 面向服务SOA&#xff08;★★★★&#xff09;微服务&#xff08;★★★★&#xff09; 基于/面向服务的&#xff08;SOA&#xff09; 在SO…

代理IP与网络安全:保障跨境电商和游戏的顺畅运行

在今天的数字时代&#xff0c;跨境电商和在线游戏已经成为全球互联网经济的两个重要组成部分。然而&#xff0c;这两者都需要强大的网络基础设施来支持其运行。同时&#xff0c;网络安全问题也变得愈发突出。在这个背景下&#xff0c;代理IP技术以及特别是Socks5代理协议&#…

企业架构LNMP学习笔记34

LVS-DR模式&#xff1a; 老师分析&#xff1a; 1、首先用户用CIP请求VIP 2、根据上图可以看到&#xff0c;不管是Director Server还是Real Server上都需要配置VIP&#xff0c;那么当用户请求到达我们的集群网络的前端路由器的时候&#xff0c;请求数据包的源地址为CIP目标地址…

C++ day 3

1、 自行封装一个栈的类&#xff0c;包含私有成员属性&#xff1a;栈的数组、记录栈顶的变量&#xff0c;成员函数完成&#xff1a;构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 stack.h #ifndef STACK_H #define STACK_H#…

Paper: 利用RNN来提取恶意软件家族的API调用模式

论文 摘要 恶意软件家族分类是预测恶意软件特征的好方法&#xff0c;因为属于同一家族的恶意软件往往有相似的行为特征恶意软件检测或分类方法分静态分析和动态分析两种&#xff1a; 静态分析基于恶意软件中包含的特定签名进行分析&#xff0c;优点是分析的范围覆盖了整个代码…

【STM32】文件系统FATFS与Flash的初步使用

文件系统简介 简介可以不看&#xff0c;直接看移植步骤 文件系统是介于应用层和底层间的模糊层。底层提供API&#xff0c;比如说使用SDIO或者SPI等读写一个字节。文件系统把这些API组合包装起来&#xff0c;并且提供一些列函数&#xff0c;我们可以使用这些函数进行更进一步的…

《protobuf》基础语法2

文章目录 枚举类型ANY 类型oneof 类型map 类型改进通讯录实例 枚举类型 protobuf里有枚举类型&#xff0c;定义如下 enum PhoneType {string home_addr 0;string work_addr 1; }同message一样&#xff0c;可分为 嵌套定义&#xff0c;文件内定义&#xff0c;文件外定义。不…

Java基础之static关键字

目录 静态的特点第一章、静态代码块第二章、静态属性第三章、静态方法调用静态方法时静态方法中调用非静态方法时 第四章、static关键字与其他关键字 友情提醒 先看文章目录&#xff0c;大致了解文章知识点结构&#xff0c;点击文章目录可直接跳转到文章指定位置。 静态的特点…

Javase | StringBuffer、StringBuilder

目录&#xff1a; 思考&#xff1a;进行字符串的频繁拼接&#xff0c;会有什么问题&#xff1f;思考&#xff1a;为什么StringBuffer是可变的&#xff1f;StringBuffer是可追加字符串的&#xff1f;StringBuffer思考&#xff1a;如何优化StringBuffer的性能&#xff1f;StringB…

IDEA控制台取消悬浮全局配置SpringBoot配置https

IDEA控制台取消悬浮 idea 全局配置 SpringBoot(Tomcat) 配置https&#xff0c;同时支持http 利用JDK生成证书 keytool -genkey -alias httpsserver -keyalg RSA -keysize 2048 -keystore server.p12 -validity 3650配置类 Configuration public class TomcatConfig {Value(&quo…

数仓问答篇(一)

数仓架构&#xff08;即席查询&#xff09; 总体来说&#xff0c;Hadoop架构在数据量较低的情况下&#xff0c;运行速度远不及MPP架构&#xff0c;但数据量一旦超过某个量级&#xff0c;Hadoop架构在吞吐量方面将非常有优势。有些大数据数据仓库产品也采用混合架构&#xff0c;…