std : : vector
一.简介
std::vector
的底层实现通常基于动态数组(dynamic array),它是一种连续分配的内存块,允许元素的快速随机访问。下面是 std::vector
的一些关键特点和底层实现细节:
-
连续内存块:
std::vector
内部使用一块连续的内存块来存储其元素,这使得元素的随机访问非常高效,因为可以通过指针算术运算来访问元素。 -
动态大小:
std::vector
允许动态地增加或减少其大小。当元素数量达到内部分配的容量时,std::vector
会重新分配更大的内存块,并将元素复制到新的内存块中。这种自动内存管理使得向量的大小可以根据需要进行调整,而不需要手动管理内存。 -
容量和大小:
std::vector
有两个重要的属性,即容量(capacity)和大小(size)。- 容量是
std::vector
当前内部分配的内存块的大小,通常大于或等于大小。当向量的大小超过容量时,会触发内存重新分配,容量会增加。 - 大小是
std::vector
中实际存储的元素数量。
- 容量是
-
动态内存分配:
std::vector
使用new
和delete
运算符(或malloc
和free
函数,取决于具体实现)来动态分配和释放内存。当需要重新分配内存时,它会为新的内存块分配内存,然后将元素从旧的内存块复制到新的内存块,最后释放旧内存。 -
异常安全:
std::vector
的实现通常会提供异常安全性,这意味着如果在内存重新分配过程中发生异常,不会导致数据丢失或内存泄漏。这是通过使用临时副本和交换技术来实现的。 -
迭代器:
std::vector
提供了迭代器(iterator)来遍历元素,迭代器通常是指针的封装,可以用于访问std::vector
中的元素。 -
内存效率:由于
std::vector
的元素存储在连续的内存块中,它在内存访问上具有很好的局部性,这有助于提高内存访问效率。
总之,std::vector
是一个非常灵活和高效的容器,它提供了动态数组的功能,使得元素的访问和管理变得非常方便。虽然 std::vector
的大小可以动态增长,但由于内存重新分配的开销,如果需要频繁插入或删除元素,可能需要考虑其他容器类型,如 std::list
或 std::deque
,它们可以更高效地支持插入和删除操作。
扩展:
动态数组(Dynamic Array)是一种数据结构,它是一个连续分配的内存块,用于存储具有相同数据类型的元素。动态数组的大小可以动态增长或缩小,以适应元素的插入和删除操作。
以下是动态数组的主要特点和操作:
-
连续内存块:动态数组的元素存储在一块连续的内存块中,这意味着元素的地址在内存中是连续的,这有助于快速随机访问元素。通过索引访问元素的时间复杂度是 O(1)。
-
动态大小:动态数组允许在运行时动态增加或减少其大小。这意味着您可以向数组中添加元素或从数组中删除元素,而不需要预先知道数组的大小。这种动态大小的特性使得动态数组非常灵活。
-
内存分配:当向动态数组添加元素并且没有足够的内存容量时,动态数组会自动分配更大的内存块,将现有元素复制到新的内存块中,并释放旧的内存块。这个过程称为重新分配(re-allocation)。
-
时间复杂度:动态数组的插入和删除操作的时间复杂度取决于插入或删除的位置。在末尾进行插入和删除操作通常是最高效的,时间复杂度为 O(1),因为不需要移动元素。在数组中间进行插入或删除操作可能需要移动后续元素,时间复杂度为 O(n)。
-
容量和大小:动态数组具有容量(capacity)和大小(size)两个重要属性。
- 容量是动态数组内部分配的内存块的大小,通常大于或等于大小。
- 大小是动态数组中实际存储的元素数量。
-
迭代器:动态数组通常提供迭代器(iterator),可以用于遍历数组中的元素。
动态数组是一种非常常见和有用的数据结构,它具有灵活性和高效性的优点。
二.运用场景
std::vector
是 C++ 标准库提供的一个动态数组容器,它在许多不同的场景中都非常有用。以下是一些常见的 std::vector
的运用场景:
-
动态数组:
std::vector
是一种动态数组,它可以根据需要自动增加或减少大小。这使得它成为存储不确定数量元素的首选选择,而不需要预先知道数组的大小。 -
数据收集:
std::vector
适用于收集大量数据,例如从文件、网络或用户输入中读取的数据。您可以使用push_back()
方法轻松添加新数据。 -
容器替代:
std::vector
可以替代 C 数组,因为它提供了更多的功能和安全性。与 C 数组不同,std::vector
知道自己的大小,而且可以动态调整大小。 -
迭代访问:如果需要通过索引或迭代器访问元素,并且需要快速随机访问能力,
std::vector
是一个很好的选择。它的时间复杂度为 O(1)。 -
栈和队列:虽然
std::vector
主要设计用于随机访问,但它也可以用作栈(先进后出)或队列(先进先出)。使用push_back()
和pop_back()
方法可以将其用作栈,而使用push_back()
和erase()
可以将其用作队列。 -
算法和数据处理:
std::vector
与标准库中的各种算法结合使用,可以用于各种数据处理任务,例如排序、查找、筛选、转换等。 -
高性能计算:在需要高性能的数值计算领域,
std::vector
通常用于存储大量数值数据,例如图形处理、科学计算、模拟等。 -
游戏开发:在游戏开发中,
std::vector
常用于存储游戏对象、粒子、动画帧等。 -
数据传输:
std::vector
可以用于数据传输,例如从文件读取数据到向量,然后将向量传递给其他处理模块。
需要注意的是,虽然 std::vector
在许多情况下非常有用,但在某些特定情况下,其他容器类型(例如 std::list
、std::deque
、std::set
、std::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或其他数据结构进行排序。然而,它们之间有一些细微的区别和优劣势:
-
可读性:使用函数指针或函数对象(结构体中的
operator()
)来定义比较操作,通常更易于理解和阅读。函数名可以明确指示比较的目的,而不需要查看结构体的成员。 -
灵活性:将比较操作封装在结构体中(函数对象方式)通常更灵活,因为你可以在结构体中存储额外的状态或配置,以影响比较的行为。这对于实现不同的排序方式很有用。
-
命名冲突:如果你有多个不同的比较操作,并且它们需要在不同的上下文中使用,将它们放入结构体中可以避免函数名冲突的问题,因为每个结构体都有自己的作用域。函数指针方式可能需要更多的命名空间管理。
-
语法:函数指针方式更紧凑,但在语法上可能略显繁琐。函数对象方式需要创建一个结构体并在排序函数中使用括号运算符来调用,这可能看起来有点冗长。
总的来说,选择哪种方式取决于你的需求和个人偏好。如果你只需要一个简单的比较操作,函数指针可能更合适。但如果你需要更复杂的比较逻辑,或者希望更好地组织和封装比较操作,那么使用函数对象(结构体中的operator()
)可能更好。
相关文章:
std : : vector
一.简介 std::vector 的底层实现通常基于动态数组(dynamic array),它是一种连续分配的内存块,允许元素的快速随机访问。下面是 std::vector 的一些关键特点和底层实现细节: 连续内存块:std::vector 内部使…...
AJAX学习笔记8 跨域问题及解决方案
AJAX学习笔记7 AJAX实现省市联动_biubiubiu0706的博客-CSDN博客 跨域:指一个域名的网页去请求另外一个域名资源.比如百度页面去请求京东页面资源. 同源与不同源三要素:协议,域名,端口 协议一致,域名一致,端口一致.才算是同源.其他一律不同源 新建项目测试: 1.window.open();…...
webhook--详解(gitee 推送)
一、简介 webhook 是一种基于 HTTP 的回调函数,可在 2 个应用编程接口(API)之间实现轻量级的事件驱动通信。是一种新型的前后端交互方式,一种对客户端-服务器模式的逆转,在传统方法中,客户端从服务器请求数…...
高速路自动驾驶功能HWP功能定义
一、功能定义 高速路自动驾驶功能HWP是指在一般畅通高速公路或城市快速路上驾驶员可以放开双手双脚,同时注意力可在较长时间内从驾驶环境中转移,做一些诸如看手机、接电话、看风景等活动,该系统最低工作速度为60kph。 如上两种不同环境和速度…...
Leetcode113. 路径总和 II
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 官方题解:力扣(LeetCode)官网 - 全…...
分布式锁之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,然后找到Modules,点击加号点击import module,将需要引进的module引进来。 然后点击Artifacts 可以看到比如说day22…这个是我现在的项目,day16是我需要引入的。那么就在红色横线上面右键点第…...
UDP协议概述
传输层里比较重要的两个协议,一个是 TCP,一个是 UDP。TCP 是面向连接的,UDP 是面向无连接的。 所谓的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结…...
Python-tracemalloc-跟踪内存分配
tracemalloc 模块是一个用于对 python 已申请的内存块进行debug的工具。它能提供以下信息: 定位对象分配内存的位置 按文件、按行统计python的内存块分配情况: 总大小、块的数量以及块平均大小。 对比两个内存快照的差异,以便排查内存泄漏 显示前10项 显示内存…...
02 CSS技巧
02 CSS技巧 clip-path 自定义形状,或者使用自带的属性画圆等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、先进先出调度器(FIFO)2、容量调度器(Capacity Scheduler)3、公平调度器(Fair …...
android上架备案公钥和md5获取工具
最近很多公司上架遇到了一个问题,就是要提供app的备案证明,现在android上架都需要备案了,但是我们的证书都是通过工具生成的,哪里知道公钥和md5那些东西呢?无论安卓备案还是ios备案都需要提供公钥和md5。 包括ios的备案…...
SpringBoot系列(12):SpringBoot集成log4j2日志配置
最近项目上有使用到log4j2日志模板配置,本文简单总结一下之前的学习笔记,如有纰漏之处,请批评指正。 1. log4j2日志依赖 使用log4j2日志模板时,需要引入相关依赖,下边的两种依赖方式均可。 1.1 使用sl4j依赖时 <…...
HTML事件列表
鼠标事件 属性描述DOMonclick当用户点击某个对象时调用的事件句柄。2oncontextmenu在用户点击鼠标右键打开上下文菜单时触发ondblclick当用户双击某个对象时调用的事件句柄。2onmousedown鼠标按钮被按下。2onmouseenter当鼠标指针移动到元素上时触发。2onmouseleave当鼠标指针…...
并发-Executor框架笔记
Executor框架 jdk5开始,把工作单元与执行机制分离开来,工作单元包括Runable和Callable,执行机制由Executor框架来提供。 Executor框架简介 Executor框架的两级调度模型 Java线程被一对一映射为本地操作系统线程 java线程启动会创建一个本…...
【C进阶】分析 C/C++程序的内存开辟与柔性数组(内有干货)
前言: 本文是对于动态内存管理知识后续的补充,以及加深对其的理解。对于动态内存管理涉及的大部分知识在这篇文章中 ---- 【C进阶】 动态内存管理_Dream_Chaser~的博客-CSDN博客 本文涉及的知识内容主要在两方面: 简单解析C/C程序…...
深入理解 JVM 之——字节码指令与执行引擎
更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 类文件结构 Write Once,Run Anywhere 对于 C 语言从程序到运行需要经过编译的过程,只有经历了编译后,我们所编写的代码才能够翻译为机器可以直接运行的二进制代码&#x…...
C++:vector
目录 一、关于vector 二、vector的相关函数 三、相关函数的使用 ①构造函数 ②size ③[] 编辑 ④push_back ⑤迭代器iterator ⑥reserve ⑦resize ⑧find ⑨insert ⑩erase ⑪sort 一、关于vector vector比较像数组 观察可知,vector有两个模板参数…...
Android Automotive编译
系统准备 安装系统 准备一台安装Ubuntu系统的机器(windows系统的机器可以通过WSL安装ubuntu系统) 安装docker 本文使用docker进行编译,因此提前安装docker。参考网络链接安装docker并设置为不使用sudo进行docker操作。 参考链接ÿ…...
什么是50ETF期权开户条件,怎么开期权交易权限?
50ETF期权是指上证50ETF期权,标的物是上证50ETF,代码是(510500),期权是一种在上证50ETF基础上进行衍生品交易的金融工具,下文科普什么是50ETF期权开户条件,怎么开期权交易权限?本文来…...
React 从入门到精通——本文来自AI创作助手
React是一个流行的JavaScript库,用于构建用户界面。以下是React入门到精通的步骤: 入门 安装React 你可以在npm上下载React包,也可以使用其他包管理器。首先需要安装node.js,然后使用以下命令安装React: npm insta…...
【51单片机实验笔记】前篇(三) 模块功能封装汇总(持续更新)
文章目录 通用函数public.hpublic.c 延时函数delay.hdelay.c LED模块数码管模块smg.hsmg.c LED点阵模块独立按键模块矩阵按键模块外部中断模块定时器模块串口通讯模块ADC模块PWM模块 通用函数 包含常用头文件,宏定义,自定义类型,函数工具等。…...
Excel VSTO开发4 -其他事件
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 4 其他事件 针对插件的事件主要有Startup、Shutdown这两个事件,在第2节中已经讲解。在开发窗口中,选择对象…...
语音识别数据的采集方法:基本流程数据类型
“人工智能是一种模仿人类功能的产品。数据采集的方法需要针对特定的场景需求。”—–Mark Brayan (澳鹏CEO) 我们一直说,对于一个高质量的人工智能产品离不开高质量的训练数据。对于不同的人工智能我们需要不同的数据对其训练。要采集正确的数据去训练特定的模型才…...
oracle数据库给用户授权DBA权限Oracle查看哪些用户具有DBA权限
oracle数据库给用户授权DBA权限 步骤一:以sysdba身份登录到Oracle数据库 在授予DBA权限之前,我们首先要以sysdba身份登录到Oracle数据库。使用以下命令登录: sqlplus / as sysdba步骤二:创建用户(如有用户跳过&#…...
024-从零搭建微服务-系统服务(六)
写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址(后端):https://gitee.com/csps/mingyue 源码地址(前端):https://gitee.com/csps…...
Arduino驱动TCS3200传感器(颜色传感器篇)
目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 TCS3200颜色传感器是一款全彩的颜色检测器,包括了一块TAOS TCS3200RGB感应芯片和4个白色LED灯,TCS3200能在一定的范围内检测和测量几乎所有的可见光。TCS3200有大量的光检测器,每个都有红绿蓝和清…...
基于Matlab实现多个数字水印案例(附上源码+数据集)
数字水印是一种在数字图像或视频中嵌入特定信息的技术,以保护知识产权和防止盗版。在本文中,我们将介绍如何使用Matlab实现数字水印。 文章目录 实现步骤源码数据集下载 实现步骤 首先,我们需要选择一个用于嵌入水印的图像。这可以是原始图像…...
C语言之指针进阶篇(2)
目录 函数指针 函数名和&函数名 函数指针的定义 函数指针的使用 函数指针陷阱 代码1 代码2 注意 函数指针数组定义 函数指针数组的使用 指向函数指针数组的指针 书写 终于军训圆满结束了,首先回顾一下指针进阶篇(1)主要是…...
C++ 进制转化入门知识(1)
一、什么是进制 进制是一种用来表示数值的系统或方法,它是基于一个特定的基数来工作的。在我们常见的几种进制中,有: 1. **二进制(基数 2)**: 二进制只用两个数字:0和1。这是计算机内部使用…...
从零开始建设企业网站/简阳seo排名优化课程
成交量(VOL)作为市场较为重要的指标之一,其量增量缩影响着价格的变动,亦看做是多空双方博弈的结果。那么如何洞察成交量(VOL)以进行交易呢? 首先我们先了解成交量(VOL)&…...
英语可以做推广的亲子类网站/南京seo网络推广
oracle中Where子句的条件顺序对性能的影响 - Oracle - 网站开发-技术教程-中国素材网 经常有人问到oracle中的Where子句的条件书写顺序是否对SQL性能有影响,我的直觉是没有影响,因为如果这个顺序有影响,Oracle应该早就能够做到自动优化&#…...
广州企立科技做网站/品牌宣传推广方案
洛谷 P1451 求细胞数量 题解 洛谷 P1451 问题描述 一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。(1<m,n<100) input 输入一个整数 m , n ( m 行…...
哪个网站可以做淘宝代码/推广app赚佣金接单平台
由于工作的需要,经常需要进行可视化展示,除了一些常用的BI工具,我也会使用python对数据进行可视化。python的第三方可视化库有很多,比如matplotlib、seaborn、plotly、bokeh、pyecharts等等。这次就来说一说,如何用pyt…...
php 手机网站开发/百度一下百度搜索入口
一、binlog 介绍服务器的二进制日志记录着该数据库的所有增删改的操作日志(前提是要在自己的服务器上开启binlog),还包括了这些操作的执行时间。为了显示这些二进制内容,我们可以使用mysqlbinlog命令来查看。用途1:主从同步用途2:…...
查询网站用什么做的/查看浏览过的历史记录百度
本文将带你了解Android应用开发arcgis for android 实现绘图功能,希望本文对大家学Android有所帮助。<一:实现绘图功能的思路1:首先需要一个点击地图的一个监听函数,可以实现点击地图画点、线、面。arcgis提供一个MapOnTouchLi…...