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

传统数组 vs vector和list

传统的数组:

int arr[10]; 传统的数组有以下的缺点:

1)长度不可修改

2)内存分配

局部数组:把数组定在函数内, 数组便是局部变量,故会被分配在栈上 但栈的大小是有限制的 ,故其在内存中不能超过1MB。 如果数组太大,可能会导致栈溢出。

int arr[1000000];  // 如果超出了内存限制,可能会失败

全局数组: 如果将数组声明为全局变量,数组会分配在数据段或 BSS 段中,不会受到栈大小的限制。但是,OJ(在线评测系统)通常对内存有严格的限制。如果数组过大,可能会超出内存限制,导致超时或内存不足的错误。

3)数组作为参数不方便。

在c语言中,将数组作为参数,实际上是传递数组的首地址,即传递的是指针,而不是整个数组。

故被调用函数只能得到数组的首地址,而无法得到数组的长度。

在做oj时要求用纯c解题,怎么解决上面的问题:

==》

1)一开始申请一个大的数组,如果局部数组的长度无法满足要求,就将数组定义为全局数组。若全局数组的占用内存超过了题目的内存限制。就是算法有问题。

我们也可以使用动态内存分配(malloc/realloc)来模拟动态数组,并手动管理内存。

2)在传参的时候传两个参数,数组的地址 和长度。

// 分配初始内存
int* arr = (int*)malloc(sizeof(int) * initial_size); //动态扩展数组
arr = (int*)realloc(arr, sizeof(int) * new_size); 
//传递数组的指针和长度
void func(int* arr, int size) {}
 

但若用c/c++,更好用的办法就是使用c++提供的vector,即动态数组。

vector的使用

都说:" 传统的静态数组 的大小在编译时就已经固定,无法在程序运行时修改。 而动态数组可以",对于这句话,通俗一点讲,就是说:

我们可以在写代码时不必定义其大小,即使定义了,我们也可以在后续的代码中使用各种方法插入或删除其元素,因为其在运行时会根据我们的代码操作自动调整其内存的 。

vector是c++提供的STL。他有一些优点;

1) 会自动处理内存分配和释放 , 免了 C 语言中常见的内存管理错误。

2) 通过 vector::size() 可以轻松获取数组的长度。

3)提供了丰富的成员函数

我们主要学习vector的增删查改。

引入

#include<vector>

增:

增操作包括初始化和插入;

1.初始化
vector<int> vec;
vector<double> vec;

注:vector不是类型,vector< type>才是类型,故下面的vec1和vec2不是同一种类型。

当然了也可以自定义一个类,从而可以定义vector<MyType>类型的变量;

struct MyType{
int val1;
double val2;
}
vector<MyType>vec;

另外,vector<int>也可以作为一种类型放在vector的<>中,

构成vector<vector<int>>,这种类型便是代表动态数组的动态数组,即二维数组。

vector<vector<int>>

在机试中,对于二维数组,推荐使用动态数组的静态数组,即下面这种写法;以应用于实现图算法中的邻接表。

vector<int> arr[10];
2.插入

插入数据使用push_back: 往动态数组的尾部插入;

我们知道,往顺序表中插入元素代价很大,而这种往数组末尾插入元素的操作非常高效,但若如果我们硬要往任意位置插入元素,该怎么办?

==》可以使用迭代器,我们稍后解答

int a;
while(scanf("%d",%a)!=EOF){vec.pushback(a);//往vec尾部插入a
}

查找

1、根据数组下标访问对应元素
//定义的这个数组下标从0到4
vector<int> vec={1,23,4};
int i=0;
printf(“vec[i]=%d\n",vec[i]);
2.遍历整个vector(for,迭代器)

vector本身携带了长度的信息,可以使用vec.size()获取长度

从而可以使用for循环遍历数组

int size=vec.size();
for(int i=0;i<size;i++){
​
}

除了用普通for循环,还可以使用迭代器

其提供了一种通用方法;可以访问不同类型的数据结构;我们可以将迭代器理解为一个高级的指针;

迭代器的类型是:动态数组类型::iterator

例vecotor<int>::iterator

对于一个数组,{1,3,5,7,9}

我们可以使用begin()来获取第一个元素的位置;使用end()来获取尾后的位置;当我们对迭代器做自增操作,他便会后移;他的用法如下:

vector<int> vec={1,3,5,7,9};
vector<int>:: iterator it;
for(it=vec.begin();it!=vec.end();it++){
printf("it=%\n",*it);
}

现在解决上面硬要往任意位置插入元素的问题:

因为迭代器可以访问到数组中任意一个位置;所以可以利用它对任意位置插入,删除元素。(insert和erase)

因为insert和erase会修改动态数组的结构,所以插入或修改完成后it的指向无意义。所以之后要对迭代器重新赋值。

但是这种插入操作最好避免使用;而使用push_back进行插入

vector<int>:: iterator it;
it=vec.begin();
vec.insert(it,2); //往it所在位置插入元素2
//注意迭代器要重新赋值
it=it+3;//it+3相当于3次++,只能在vector中使用
3.通过元素信息查找其位置

1.删除一个元素

我们可以使用pop_back()删除最后一个位置的元素。

vec.pop_back();

同样的,如果我们硬要删除一个位置的元素,可以使用迭代器配合erase函数。

vecor.erase(it);
2.把vector清空
vector.clear()

list的使用

前面我们讲过,即使使用迭代器配合insert和erase函数能够在任意位置对数组进行增加和删除操作,但是还是不推荐那样做。因为,如前面所言,顺序表的线性结构进行这样的操作真的很低效。所以,如果我们硬要做,就不能使用传统的线性结构,而得使用链式结构。

c++标准库为我们提供了一个链式结构的顺序表,叫list。

list的底层原理是一个双向链表。

引入

#include<list>

增 insert

前面我们在vector中对于迭代器,使用了it+=3表示迭代器it++了3次,但是因为链表中不支持随机访问,故不支持加法运算符,故只能靠自增3次来实现;

list<int> ls={1,3,4,5,6};
//获取迭代器
list<int>::iterator it=ls.begin();
it++;
it++;
it++;
ls.insert(it, 10);

it.erase();

遍历list

for(it=ls.begin();it!=ls.end();it++){
printf("it=%d\n",*it);
}

vector和list的选择

若一个题目中要求使用一个线性的数据结构,我们首选vector,

但如果你发现这个vector在使用的过程中存在着大量的对中间元素进插入和删除的操作,就改用list。

补充解惑:

1.为什么往线性表中的任意元素插入或删除元素很低效?

====》

线性表(如 vector)的底层是一个连续的内存块(数组)。在往数组中间插入或删除元素时,需要移动其他的元素。

因此 插入和删除最坏情况下的事件复杂度都是为o(n)。

2.list的增删改查都是使用迭代器完成的吗?

===>

是的,list 的增删改查主要是通过迭代器来完成的。

由于 list 是基于链表实现的, 因此没有下标访问的方式,只能通过迭代器进行增删改查。 迭代器提供了一个统一的接口来遍历、修改 list 中的元素,增加了代码的灵活性和可移植性。

ls.insert(it, 10);

ls.erase(it);

std::cout << *it << " ";

相关文章:

传统数组 vs vector和list

传统的数组&#xff1a; int arr[10]&#xff1b; 传统的数组有以下的缺点&#xff1a; 1&#xff09;长度不可修改 2)内存分配 局部数组:把数组定在函数内&#xff0c; 数组便是局部变量&#xff0c;故会被分配在栈上 但栈的大小是有限制的 &#xff0c;故其在内存中不能超…...

CRMEB 多商户版v3.0.1源码全开源+PC端+Uniapp前端+搭建教程

一.介绍 crmeb多商户是一套B2B2C商家入驻模式的平台多商户商城系统&#xff0c;系统支持平台自营、联营、招商等多种运营模式&#xff0c;可满足企业新零售、批发、分销、预售、O2O、多店、商铺入驻等各种业务需求。 后端全开源、uniapp多端可编译&#xff01; 二、搭建教程…...

【ESP32】ESP-IDF开发 | WiFi开发 | HTTPS服务器 + 搭建例程

1. 简介 1.1 HTTPS HTTPS&#xff08;HyperText Transfer Protocol over Secure Socket Layer&#xff09;&#xff0c;全称安全套接字层超文本传输协议&#xff0c;一般理解为HTTPSSL/TLS&#xff0c;通过SSL证书来验证服务器的身份&#xff0c;并为浏览器和服务器之间的通信…...

Vue2 中使用 UniApp 时,生命周期钩子函数总结

在 Vue2 中使用 UniApp 时&#xff0c;生命周期钩子函数是一个重要的概念。它允许开发者在特定的时间点运行代码&#xff0c;管理组件的生命周期。以下是 Vue2 中 UniApp 常用的生命周期钩子函数总结&#xff1a; 1. beforeCreate 说明: 组件实例刚被创建&#xff0c;此时数据…...

如何在 Vue 3 中使用 Vue Router 和 Vuex

在 Vue 3 中使用 Vue Router 1. 安装 Vue Router 在项目根目录下&#xff0c;通过 npm 或 yarn 安装 Vue Router 4&#xff08;适用于 Vue 3&#xff09;&#xff1a; npm install vue-router4 # 或者使用 yarn yarn add vue-router42. 创建路由配置文件 在 src 目录下创建…...

Fiori APP配置中的Semantic object 小bug

在配置自开发程序的Fiori Tile时&#xff0c;需要填入Semantic Object。正常来说&#xff0c;是需要通过事务代码/N/UI2/SEMOBJ来提前新建的。 但是在S4 2022中&#xff0c;似乎存在一个bug&#xff0c;即无需新建也能输入自定义的Semantic Object。 如下&#xff0c;当我们任…...

【触想智能】工业显示器和普通显示器的区别以及工业显示器的主要应用领域分析

在现代工业中&#xff0c;工业显示器被广泛应用于各种场景&#xff0c;从监控系统到生产控制&#xff0c;它们在实时数据显示、操作界面和信息传递方面发挥着重要作用。与普通显示器相比&#xff0c;工业显示器在耐用性、可靠性和适应特殊环境的能力上有着显著的差异。 触想工业…...

BPMN.js 与 DeepSeek 集成:打造个性化 Web 培训项目的秘诀

在数字化时代&#xff0c;Web培训项目的需求日益增长&#xff0c;特别是对于程序员群体&#xff0c;他们寻求高效、灵活的方式来提升自己的技能。本文将深入探讨如何评估BPMN.js与DeepSeek集成方案&#xff0c;以满足开发Web培训项目的需求。 BPMN.js 的优势 BPMN.js是一个专…...

第二月:学习 NumPy、Pandas 和 Matplotlib 是数据分析和科学计算的基础

以下是一个为期 **1 个月&#xff08;30 天&#xff09;**的详细学习计划&#xff0c;精确到每天的学习内容和练习作业&#xff0c;帮助你系统地掌握 NumPy、Pandas 和 Matplotlib 的核心功能。 第 1 周&#xff1a;NumPy 基础 Day 1&#xff1a;NumPy 简介与数组创建 学习内…...

安全测试|SSRF请求伪造

前言 SSRF漏洞是一种在未能获取服务器权限时&#xff0c;利用服务器漏洞&#xff0c;由攻击者构造请求&#xff0c;服务器端发起请求的安全漏洞&#xff0c;攻击者可以利用该漏洞诱使服务器端应用程序向攻击者选择的任意域发出HTTP请求。 很多Web应用都提供了从其他的服务器上…...

Flink提交pyflink任务

1.官方文档&#xff1a; flink1.14:https://nightlies.apache.org/flink/flink-docs-release-1.14/docs/deployment/cli/#submitting-pyflink-jobs flink1.18:https://nightlies.apache.org/flink/flink-docs-release-1.18/docs/deployment/cli/#submitting-pyflink-jobs 2.提…...

对称算法模式之CTR

Note 计数器模式&#xff0c;通过加密递增计数器生成密钥流&#xff0c;后密钥流与明文分组异或得密文分组可并行性进行加密或者解密&#xff0c;性能较高明文可以是任意长度&#xff0c;不需要填充可以直接加密或解密指定块&#xff0c;块与块间不具有依赖关系 参数说明 任…...

Map 和 Set

目录 一、搜索 概念&#xff1a; 模型&#xff1a; 二、Map ​编辑 1.Map 实例化&#xff1a; 2. Map的常见方法&#xff1a; 3.Map的常见方法演示&#xff1a; 1. put(K key, V value)&#xff1a;添加键值对 3. containsKey(Object key)&#xff1a;检查键是否存在 4.…...

STOMP协议

引用&#xff1a;https://blog.csdn.net/print_helloword/article/details/142597122 什么是STOMP协议 STOMP (simple text oriented messaging protocol): 一种简单的&#xff0c;基于文本的消息传输协议&#xff0c;&#xff0c;&#xff0c;最初是为了解决在消息队列中&am…...

手动埋点的demo

上代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>埋点示例</title> </head><b…...

大模型开发实战篇5:多模态--文生图模型API

大模型文生图是一种基于人工智能大模型的技术&#xff0c;能够将自然语言文本描述转化为对应的图像。目前非常火的AI大模型赛道&#xff0c;有很多公司在此赛道竞争。详情可看这篇文章。 今天我们来看下如何调用WebAPI来实现文生图功能。我们一般都会将OpenAI的接口&#xff0…...

【大模型】DeepSeek 高级提示词技巧使用详解

目录 一、前言 二、DeepSeek 通用提示词技巧 2.1 DeepSeek 通用提示词技巧总结 三、DeepSeek 进阶使用技巧 3.1 DeepSeek一个特定角色的人设 3.1.1 为DeepSeek设置角色操作案例一 3.1.2 为DeepSeek设置角色操作案例二 3.2 DeepSeek开放人设升级 3.2.1 特殊的人设&#…...

【第14章:神经符号集成与可解释AI—14.2 可解释AI技术:LIME、SHAP等的实现与应用案例】

在这里插入图片描述 凌晨三点的ICU病房,值班医生李主任盯着AI辅助诊断系统的红色警报——这套准确率高达95%的深度学习系统,突然建议对一位肾衰竭患者进行肝移植手术。正当医疗组陷入混乱时,李主任打开了系统的"解释模式",屏幕上立即跳出SHAP分析图:模型误将CT…...

Python中使用Minio实现图像或视频文件的存储

目录 一、Minio的基本介绍1.Minio是什么2.Minio的优势 二、使用步骤1.启动Minio2.创建桶3.在Python中使用Minio3.1安装并导入minio包3.2创建mino_utils工具类 三、操作演示1.引入minio_utils工具类2.上传视频文件3.获取视频文件 总结 一、Minio的基本介绍 1.Minio是什么 Mini…...

Kubernetes-master 组件

以下是Kubernetes Master Machine的组件。 etcd 它存储集群中每个节点可以使用的配置信息。它是一个高可用性键值存储&#xff0c;可以在多个节点之间分布。只有Kubernetes API服务器可以访问它&#xff0c;因为它可能具有一些敏感信息。这是一个分布式键值存储&#xff0c;所…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...