当前位置: 首页 > news >正文

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())可能更好。

相关文章:

std : : vector

一.简介 std::vector 的底层实现通常基于动态数组&#xff08;dynamic array&#xff09;&#xff0c;它是一种连续分配的内存块&#xff0c;允许元素的快速随机访问。下面是 std::vector 的一些关键特点和底层实现细节&#xff1a; 连续内存块&#xff1a;std::vector 内部使…...

AJAX学习笔记8 跨域问题及解决方案

AJAX学习笔记7 AJAX实现省市联动_biubiubiu0706的博客-CSDN博客 跨域:指一个域名的网页去请求另外一个域名资源.比如百度页面去请求京东页面资源. 同源与不同源三要素:协议,域名,端口 协议一致,域名一致,端口一致.才算是同源.其他一律不同源 新建项目测试: 1.window.open();…...

webhook--详解(gitee 推送)

一、简介 webhook 是一种基于 HTTP 的回调函数&#xff0c;可在 2 个应用编程接口&#xff08;API&#xff09;之间实现轻量级的事件驱动通信。是一种新型的前后端交互方式&#xff0c;一种对客户端-服务器模式的逆转&#xff0c;在传统方法中&#xff0c;客户端从服务器请求数…...

高速路自动驾驶功能HWP功能定义

一、功能定义 高速路自动驾驶功能HWP是指在一般畅通高速公路或城市快速路上驾驶员可以放开双手双脚&#xff0c;同时注意力可在较长时间内从驾驶环境中转移&#xff0c;做一些诸如看手机、接电话、看风景等活动&#xff0c;该系统最低工作速度为60kph。 如上两种不同环境和速度…...

Leetcode113. 路径总和 II

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 官方题解&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全…...

分布式锁之redis实现

docker安装redis 拉取镜像 docker pull redis:6.2.6 查看镜像 启动容器并挂载目录 需要挂在的data和redis.conf自行创建即可 docker run --restart always -d -v /usr/local/docker/redis/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/redis/data:/dat…...

Idea中如何在一个项目中引入其他子模块?

首先在Settings打开Project Structure&#xff0c;然后找到Modules&#xff0c;点击加号点击import module&#xff0c;将需要引进的module引进来。 然后点击Artifacts 可以看到比如说day22…这个是我现在的项目&#xff0c;day16是我需要引入的。那么就在红色横线上面右键点第…...

UDP协议概述

传输层里比较重要的两个协议&#xff0c;一个是 TCP&#xff0c;一个是 UDP。TCP 是面向连接的&#xff0c;UDP 是面向无连接的。 所谓的建立连接&#xff0c;是为了在客户端和服务端维护连接&#xff0c;而建立一定的数据结构来维护双方交互的状态&#xff0c;用这样的数据结…...

Python-tracemalloc-跟踪内存分配

tracemalloc 模块是一个用于对 python 已申请的内存块进行debug的工具。它能提供以下信息: 定位对象分配内存的位置 按文件、按行统计python的内存块分配情况: 总大小、块的数量以及块平均大小。 对比两个内存快照的差异&#xff0c;以便排查内存泄漏 显示前10项 显示内存…...

02 CSS技巧

02 CSS技巧 clip-path 自定义形状&#xff0c;或者使用自带的属性画圆等circle HTML结构 <body><div class"container"></div> </body>CSS结构 使用*polygon*自定义形状 .container {width: 300px;height: 300px;background-color: re…...

Yarn资源调度器

文章目录 一、Yarn资源调度器1、架构2、Yarn工作机制3、HDFS、YARN、MR关系4、作业提交之HDFS&MapReduce 二、Yarn调度器和调度算法1、先进先出调度器&#xff08;FIFO&#xff09;2、容量调度器&#xff08;Capacity Scheduler&#xff09;3、公平调度器&#xff08;Fair …...

android上架备案公钥和md5获取工具

最近很多公司上架遇到了一个问题&#xff0c;就是要提供app的备案证明&#xff0c;现在android上架都需要备案了&#xff0c;但是我们的证书都是通过工具生成的&#xff0c;哪里知道公钥和md5那些东西呢&#xff1f;无论安卓备案还是ios备案都需要提供公钥和md5。 包括ios的备案…...

SpringBoot系列(12):SpringBoot集成log4j2日志配置

最近项目上有使用到log4j2日志模板配置&#xff0c;本文简单总结一下之前的学习笔记&#xff0c;如有纰漏之处&#xff0c;请批评指正。 1. log4j2日志依赖 使用log4j2日志模板时&#xff0c;需要引入相关依赖&#xff0c;下边的两种依赖方式均可。 1.1 使用sl4j依赖时 <…...

HTML事件列表

鼠标事件 属性描述DOMonclick当用户点击某个对象时调用的事件句柄。2oncontextmenu在用户点击鼠标右键打开上下文菜单时触发ondblclick当用户双击某个对象时调用的事件句柄。2onmousedown鼠标按钮被按下。2onmouseenter当鼠标指针移动到元素上时触发。2onmouseleave当鼠标指针…...

并发-Executor框架笔记

Executor框架 jdk5开始&#xff0c;把工作单元与执行机制分离开来&#xff0c;工作单元包括Runable和Callable&#xff0c;执行机制由Executor框架来提供。 Executor框架简介 Executor框架的两级调度模型 Java线程被一对一映射为本地操作系统线程 java线程启动会创建一个本…...

【C进阶】分析 C/C++程序的内存开辟与柔性数组(内有干货)

前言&#xff1a; 本文是对于动态内存管理知识后续的补充&#xff0c;以及加深对其的理解。对于动态内存管理涉及的大部分知识在这篇文章中 ---- 【C进阶】 动态内存管理_Dream_Chaser&#xff5e;的博客-CSDN博客 本文涉及的知识内容主要在两方面&#xff1a; 简单解析C/C程序…...

深入理解 JVM 之——字节码指令与执行引擎

更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 类文件结构 Write Once&#xff0c;Run Anywhere 对于 C 语言从程序到运行需要经过编译的过程&#xff0c;只有经历了编译后&#xff0c;我们所编写的代码才能够翻译为机器可以直接运行的二进制代码&#x…...

C++:vector

目录 一、关于vector 二、vector的相关函数 三、相关函数的使用 ①构造函数 ②size ③[] ​编辑 ④push_back ⑤迭代器iterator ⑥reserve ⑦resize ⑧find ⑨insert ⑩erase ⑪sort 一、关于vector vector比较像数组 观察可知&#xff0c;vector有两个模板参数…...

Android Automotive编译

系统准备 安装系统 准备一台安装Ubuntu系统的机器&#xff08;windows系统的机器可以通过WSL安装ubuntu系统&#xff09; 安装docker 本文使用docker进行编译&#xff0c;因此提前安装docker。参考网络链接安装docker并设置为不使用sudo进行docker操作。 参考链接&#xff…...

什么是50ETF期权开户条件,怎么开期权交易权限?

50ETF期权是指上证50ETF期权&#xff0c;标的物是上证50ETF&#xff0c;代码是&#xff08;510500&#xff09;&#xff0c;期权是一种在上证50ETF基础上进行衍生品交易的金融工具&#xff0c;下文科普什么是50ETF期权开户条件&#xff0c;怎么开期权交易权限&#xff1f;本文来…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...