当前位置: 首页 > 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;本文来…...

构建企业级日志监控系统:Visual Syslog Server技术架构深度解析

构建企业级日志监控系统&#xff1a;Visual Syslog Server技术架构深度解析 【免费下载链接】visualsyslog Syslog Server for Windows with a graphical user interface 项目地址: https://gitcode.com/gh_mirrors/vi/visualsyslog 在当今复杂的IT基础设施环境中&#…...

2025 - 2026年国资跑步入场脑机接口,重新定义游戏规则!

突发&#xff01;国资入场脑机接口赛道2025 - 2026年&#xff0c;脑机接口赛道的资本格局悄然生变。从IT桔子融资数据来看&#xff0c;国资/政府基金密集出现在近一年的轮次中&#xff1a;上海国投先导、国投创合跟投阶梯医疗5亿战略融资&#xff1b;浦东创投、张江科投联手投资…...

单片机软件架构师使用Taotoken多模型对比分析内存分配策略

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 单片机软件架构师使用Taotoken多模型对比分析内存分配策略 在嵌入式软件开发中&#xff0c;内存分配策略的选择直接影响着系统的实…...

通过Taotoken实现按Token计费的多模型批量测试脚本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 通过Taotoken实现按Token计费的多模型批量测试脚本 基础教程类&#xff0c;针对需要对多个模型进行性能或效果评估的开发者&#x…...

别再死记硬背了!用PyTorch和TensorFlow动手实现四种池化层,直观理解它的作用

用代码可视化理解深度学习中的池化层&#xff1a;PyTorch与TensorFlow实战指南 当你第一次听说"池化层"这个概念时&#xff0c;是否也感到困惑&#xff1f;为什么神经网络需要这样一个"缩小"图像的层&#xff1f;本文将通过PyTorch和TensorFlow两种框架的实…...

MTK平台Android 11定制:Settings里那些被“砍掉”的功能,到底怎么改的?

MTK平台Android 11深度定制&#xff1a;Settings功能裁剪的工程实践与源码解析 在移动设备系统定制领域&#xff0c;MTK平台因其高度集成的硬件方案和灵活的软件架构&#xff0c;成为众多厂商的首选。当我们基于MTK平台进行Android 11系统级定制时&#xff0c;Settings应用的模…...

MooseFS企业级部署方案:多数据中心架构设计与实施指南

MooseFS企业级部署方案&#xff1a;多数据中心架构设计与实施指南 【免费下载链接】moosefs MooseFS Distributed Storage – Open Source, Petabyte, Fault-Tolerant, Highly Performing, Scalable Network Distributed File System / Software-Defined Storage 项目地址: h…...

自动化营销系统:高效破解市场-SDR销售线索流转堵点

在B2B营销中&#xff0c;线索从“获取”到“转化”的过程&#xff0c;往往伴随着大量的手动操作、信息断层和跟进滞后。尤其是市场团队与SDR&#xff08;销售开发代表&#xff09;之间的协作&#xff0c;常常成为线索流转的“瓶颈”。如何高效、规范地将市场获取的Leads转化为可…...

手把手教你用GD32F303定时器PWM驱动LED,从寄存器配置到CubeMX生成代码

GD32F303定时器PWM开发全攻略&#xff1a;寄存器配置与图形化工具实战对比 在嵌入式开发领域&#xff0c;PWM&#xff08;脉冲宽度调制&#xff09;技术如同一位无声的指挥家&#xff0c;精准控制着LED亮度、电机转速等关键参数。对于GD32F303这款高性能ARM Cortex-M4内核微控制…...

Unity项目瘦身实战:彻底搞懂Library文件夹,轻松清理几十个G的缓存

Unity项目瘦身实战&#xff1a;彻底搞懂Library文件夹&#xff0c;轻松清理几十个G的缓存 当你打开资源管理器&#xff0c;发现Unity项目的Library文件夹已经吞噬了50GB磁盘空间时&#xff0c;那种窒息感就像发现衣柜里塞满了十年没穿过的旧衣服。这个隐藏在项目根目录下的&quo…...