C++面试:向量vector和列表list介绍

目录

vector

list 

list和vector的区别

1. 底层实现:

2. 动态性和静态性:

3. 内存管理:

4. 迭代器和指针:

5. 访问效率:

6. 适用场景:


vector

  std::vector 是 C++ STL 提供的动态数组容器,提供了多种操作。以下是一些常见的 std::vector 操作,一一列举出来

初始化和基本操作

std::vector<int> myVector;  // 初始化一个空的向量
myVector.push_back(1);     // 添加元素到向量末尾
myVector[2] = 10;          // 访问和修改向量元素
int size = myVector.size(); // 获取向量大小

插入和删除元素

myVector.insert(myVector.begin() + 1, 4); // 插入元素到指定位置
myVector.erase(myVector.begin() + 2);    // 删除指定位置的元素
myVector.clear();                         // 清空向量

 范围操作

std::vector<int> source = {1, 2, 3, 4, 5};
std::vector<int> destination = source; // 复制整个向量
std::vector<int> subVector(source.begin() + 1, source.begin() + 4); // 复制部分向量

元素访问和遍历

int elementAtIndex2 = myVector[2]; // 使用下标访问元素// 使用迭代器访问元素
for (std::vector<int>::iterator it = myVector.begin(); it != myVector.end(); ++it) {// ...
}// 使用范围-based for 循环
for (const auto& element : myVector) {// ...
}

 其他常用方法

int firstElement = myVector.front(); // 获取第一个元素
int lastElement = myVector.back();   // 获取最后一个元素
bool isEmpty = myVector.empty();     // 判断向量是否为空
myVector.resize(8);                  // 改变向量大小

移动语义和右值引用

std::vector<std::string> source = {"apple", "orange", "banana"};
std::vector<std::string> destination(std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));

使用迭代器进行插入和删除

std::vector<int>::iterator it = myVector.begin() + 2;
myVector.insert(it, 10);   // 在指定位置插入元素
myVector.erase(it + 3);    // 在指定位置删除元素

在特定条件下删除元素

myVector.erase(std::remove(myVector.begin(), myVector.end(), 3), myVector.end());

使用函数对象进行元素变换

struct Square {int operator()(int x) const {return x * x;}
};std::transform(myVector.begin(), myVector.end(), myVector.begin(), Square());

使用 std::find 查找元素

int searchElement = 5;
auto it = std::find(myVector.begin(), myVector.end(), searchElement);
if (it != myVector.end()) {// 元素找到的处理
}

排序向量

std::sort(myVector.begin(), myVector.end());

 反向遍历向量

// 使用逆向迭代器
for (auto it = myVector.rbegin(); it != myVector.rend(); ++it) {// ...
}

查找最小和最大元素

auto minElement = std::min_element(myVector.begin(), myVector.end());
auto maxElement = std::max_element(myVector.begin(), myVector.end());

计算向量的和

int sum = std::accumulate(myVector.begin(), myVector.end(), 0);

使用 lambda 表达式进行元素变换

// 将所有元素加倍
std::transform(myVector.begin(), myVector.end(), myVector.begin(), [](int x) { return x * 2; });

使用 std::copy 复制向量

std::vector<int> copyVector;
std::copy(myVector.begin(), myVector.end(), std::back_inserter(copyVector));

将向量转为数组

int* arrayData = myVector.data();

遍历并修改所有元素

for (auto& element : myVector) {element *= 2;
}

使用自定义比较函数进行排序

// 按照元素的绝对值进行升序排序
std::sort(myVector.begin(), myVector.end(), [](int a, int b) {return std::abs(a) < std::abs(b);
});

使用 std::reverse 反转向量

std::reverse(myVector.begin(), myVector.end());

list 

1. 初始化和基本操作:

#include <list>std::list<int> myList;           // 初始化一个空的列表
std::list<int> myList2 = {1, 2};  // 使用初始化列表初始化列表myList.push_back(3);              // 在列表末尾添加元素
myList.push_front(2);             // 在列表开头添加元素int frontElement = myList.front(); // 获取列表第一个元素
int backElement = myList.back();   // 获取列表最后一个元素myList.pop_back();                 // 删除列表末尾的元素
myList.pop_front();                // 删除列表开头的元素

2. 插入和删除元素: 

#include <list>std::list<int> myList = {1, 2, 3, 4};auto it = myList.begin();
++it; // 移动到第二个元素的位置myList.insert(it, 5);     // 在指定位置插入元素
myList.erase(it);         // 删除指定位置的元素myList.remove(3);         // 删除列表中所有值为3的元素
myList.clear();           // 清空列表

3. 迭代器和遍历:

#include <list>std::list<int> myList = {1, 2, 3, 4};// 使用迭代器遍历列表
for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {// ...
}// 使用范围-based for 循环
for (const auto& element : myList) {// ...
}

5. 查找和替换:

#include <list>
#include <algorithm>std::list<int> myList = {1, 2, 3, 4};auto it = std::find(myList.begin(), myList.end(), 3); // 查找元素if (it != myList.end()) {// 元素找到的处理
}myList.unique(); // 删除相邻重复元素

6. 合并和拆分:

#include <list>std::list<int> myList1 = {1, 3, 5};
std::list<int> myList2 = {2, 4, 6};myList1.merge(myList2);  // 合并两个已排序的列表std::list<int> newList;
auto it = std::find(myList1.begin(), myList1.end(), 3);
newList.splice(newList.begin(), myList1, it, myList1.end()); // 从一个列表移动元素到另一个列表

7. 使用自定义类型:

#include <list>
#include <iostream>// 自定义类型
struct Person {std::string name;int age;
};int main() {// 使用自定义类型的列表std::list<Person> people = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 22}};// 访问和修改自定义类型的列表元素auto it = people.begin();it->age = 32;// 迭代自定义类型的列表元素for (const auto& person : people) {std::cout << person.name << " - " << person.age << " years old" << std::endl;}return 0;
}

 8. 将列表转为数组:

#include <list>
#include <vector>std::list<int> myList = {1, 2, 3, 4};// 将列表转为数组
std::vector<int> myVector(myList.begin(), myList.end());

9. 自定义比较函数进行排序 

#include <list>
#include <algorithm>
#include <iostream>// 自定义比较函数
bool compare(int a, int b) {return a > b;  // 降序排序
}int main() {std::list<int> myList = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};// 使用自定义比较函数进行排序myList.sort(compare);// 输出排序后的列表元素for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

list和vector的区别

1. 底层实现:

  • std::list 使用双向链表实现,每个元素存储下一个元素和前一个元素的地址,因此在插入和删除元素时,效率较高。但是,由于不是连续存储的,随机访问元素的性能较差。

  • std::vector 使用动态数组实现,元素在内存中是连续存储的,支持通过索引进行快速的随机访问。但在插入和删除元素时,可能需要移动其他元素,因此效率相对较低。

2. 动态性和静态性:

  • std::list 是动态容器,可以在运行时动态增加或删除元素。

  • std::vector 是静态容器,其大小在声明时就已经确定,无法动态改变。需要重新分配内存和复制元素才能改变其大小。

3. 内存管理:

  • std::list 每个元素都有独立的内存块,插入和删除元素时不需要移动其他元素,因此内存管理较为灵活。但是,由于链表结构,会带来额外的指针开销。

  • std::vector 元素在内存中是紧密排列的,随机访问效率高。但插入和删除元素可能需要移动其他元素,导致额外的开销。

4. 迭代器和指针:

  std::list 提供双向迭代器,支持双向遍历。

std::list<int>::iterator it = myList.begin();

   std::vector 提供随机访问迭代器,支持快速的随机访问

std::vector<int>::iterator it = myVector.begin();

5. 访问效率:

  • std::list 随机访问效率较低,因为需要沿着链表逐个移动。但在插入和删除元素时,std::list 的性能较好,尤其是在中间位置。

  • std::vector 允许通过索引进行快速的随机访问,因为元素在内存中是连续存储的。然而,在中间插入或删除元素时可能涉及元素的移动,效率较低。

6. 适用场景:

  • std::list 适用于频繁的插入和删除操作,以及在序列中间位置进行操作的场景。

  • std::vector 适用于需要高效随机访问的场景,以及在序列末尾进行插入和删除操作的场景。

        选择使用 std::list 还是 std::vector 取决于具体的使用场景和操作需求。需要根据插入、删除、访问等操作的频率和性能要求来选择合适的容器

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

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

相关文章

嵌入式Linux:如何进行嵌入式Linux开发?

目录 1、裸机开发 2、SDK开发 3、驱动开发 3.1、字符设备驱动 3.2、块设备驱动 3.3、网络设备驱动 嵌入式Linux开发主要有三种方式&#xff1a;裸机开发、SDK开发和驱动开发。 1、裸机开发 裸机开发通常指在没有操作系统支持的环境中直接在硬件上运行程序的开发。这种开发方式要…

基于JavaWeb+SSM+Vue停车场微信小程序系统的设计和实现

基于JavaWebSSMVue停车场微信小程序系统的设计和实现 滑到文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 滑到文末获取源码 Lun文目录 目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想 1 2相关…

【Java 设计模式】结构型之外观模式

文章目录 1. 定义2. 应用场景3. 代码实现结语 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c; 它为复杂系统提供了一个简化的接口&#xff0c;隐藏了系统的复杂性&#xff0c;使得客户端更容易使用系统。外观模式通过创建一个包装类&#x…

【ASP.NET Core 基础知识】--路由和请求处理--路由概念(一)

在Web应用中&#xff0c;路由是一个至关重要的概念&#xff0c;它负责将用户的请求映射到相应的处理程序&#xff0c;以确保正确的页面或资源被呈现给用户。通过将用户请求与适当的处理程序关联起来&#xff0c;使得应用能够以有序和可维护的方式响应用户的操作。 一、ASP.NET…

【网络安全】-入门版

secure 一、基本工具1、metasploit framework ps.本着兴趣爱好&#xff0c;加强电脑的安全防护能力&#xff0c;并严格遵守法律和道德规范。一、基本工具 1、metasploit framework msf&#xff08;metasploit framework&#xff09;是一个开源的渗透测试框架&#xff0c;用于…

小程序系列--10.小程序WXS 脚本

一、概述 1. 什么是 wxs&#xff1f; WXS&#xff08;WeiXin Script&#xff09;是小程序独有的一套脚本语言&#xff0c;结合 WXML&#xff0c;可以构建出页面的结构。 2. wxs 的应用场景 wxml 中无法调用在页面的 .js 中定义的函数&#xff0c;但是&#xff0c;wxml 中可…

Vagrant安装Oracle Data Guard环境示例

在Windows 11下&#xff0c;通过Vagrant安装标准的Data Guard环境&#xff08;默认为non-CDB模式&#xff09;&#xff0c;耗时约26分钟&#xff0c;共生成2台虚机。以下为安装日志&#xff1a; ...host2: Welcome to DGMGRL, type "help" for information.host2: C…

《Python数据分析实战》

环境搭建 定义变量名时要遵循的规则&#xff1a; 变量名必须以字母或下画线开始&#xff0c;名字中间只能由字母、数字和下画线组成长度不能超过255个字符变量名在有效范围内必须具有唯一性不能使用保留字&#xff08;关键字&#xff09;区分大小写 不能对元组中的元素做修改…

分布式锁注解SyncLock

一、目标&#xff1a; 1、简化手动开关锁的重复代码&#xff08;专注业务本身&#xff09; 2、集成不同分布式锁解决方案&#xff08;锁不同使用方式不同&#xff09; 3、规范锁的命名和异常信息内容&#xff08;内容不规范&#xff0c;不易于理解和维护&#xff09; 4、避免事…

pyspark笔记:over

1 方法介绍 在 PySpark 中&#xff0c;over 函数是一个非常重要的概念&#xff0c;尤其是在使用窗口函数&#xff08;例如 row_number, rank, dense_rank, lead, lag 等&#xff09;时。over 函数允许你对一个数据集进行分组&#xff0c;然后在每个分组内应用窗口函数。 1.1 …

Appium 环境配置

Appium 是一个开源的、跨平台的测试框架&#xff0c;可以用来测试 Native App、混合应用、移动 Web 应用&#xff08;H5 应用&#xff09;等&#xff0c;也是当下互联网企业实现移动自动化测试的重要工具。Appium 坚持的测试理念&#xff1a; •无需用户对 App 进行任何修改或…

2024年一整年的考试报名时间表不许再错过考试啦

每个大学生都不能错过的超全考试报名表&#xff01; 有了它谁还会再错过考试哇&#xff01;&#xff01;&#xff01; 1月报名 专转本考试 12月底-1月报名 卫生资格考试 1月中旬报名 教师资格证笔试 1月报名 各省省考 2月报名 医师资格考试 2月报名 初级高级会计 2月报名 计算机…

Java 基础 - Java 多态性详解与实例解析

Java 多态性详解与实例解析 多态性是面向对象编程中的一个重要概念,它允许不同类型的对象以相同的方式对待,从而提高了代码的灵活性和可维护性。在 Java 中,多态性通过继承和方法重写实现,让我们深入了解一下。 什么是多态性? 多态性是指在同一类型的变量调用相同方法时…

架构篇05-复杂度来源:高可用

文章目录 计算高可用存储高可用高可用状态决策小结 今天&#xff0c;我们聊聊复杂度的第二个来源高可用。 参考维基百科&#xff0c;先来看看高可用的定义。 系统无中断地执行其功能的能力&#xff0c;代表系统的可用性程度&#xff0c;是进行系统设计时的准则之一。 这个定义…

快速入门:使用 Gemini Embeddings 和 Elasticsearch 进行向量搜索

Gemini 是 Google DeepMind 开发的多模态大语言模型家族&#xff0c;作为 LaMDA 和 PaLM 2 的后继者。由 Gemini Ultra、Gemini Pro 和 Gemini Nano 组成&#xff0c;于 2023 年 12 月 6 日发布&#xff0c;定位为 OpenAI 的竞争者 GPT-4。 本教程演示如何使用 Gemini API 创建…

【代码整理】基于COCO格式的pytorch Dataset类实现

import模块 import numpy as np import torch from functools import partial from PIL import Image from torch.utils.data.dataset import Dataset from torch.utils.data import DataLoader import random import albumentations as A from pycocotools.coco import COCO …

java SSM园林绿化管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM园林绿化管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

网易真的大规模裁员吗?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 以前互联网公司裁员&#xff0c;大家不紧张&#xff0c;因为容易找工作&#xff0c;而现在不知道怎么回事&#xff0c;只要以提高某某公司裁员&#xff0c;这就能迅速登上热榜。 这不&#xff0c;最近网传网易裁员1…

二、项目开发计划模板

1&#xff0e;引言 1.1编写目的 1.2项目背景 1.3定义 1.4参考资料 2&#xff0e;项目概述 2.1工作内容 2.2条件与限制 2.3产品 2.4运行环境 2.5服务 2.6验收标准 3&#xff0e;实施计划 3.1任务分解 3.2进度 3.3预算 3.4关键问题 4&#xff…

Linux的IO文件操作和文件系统

前要&#xff1a;本次我想给您带来关于 IO 和文件的知识&#xff0c;而文件在本系列中分为内存上的文件和磁盘上的文件。 1.文件概念 1.1.文件读写 在谈及系统接口之前&#xff0c;我们先来从 C 语言的角度来谈及一些前要知识&#xff0c;以辅助我们后续来理解系统 IO。 我们…