[C++面试] 标准容器面试点

一、入门

1、vectorlist的区别

[C++面试] vector 面试点总结

vector 是动态数组,它将元素存储在连续的内存空间中。支持随机访问,即可以通过下标快速访问任意位置的元素,时间复杂度为 O(1),准确点是均摊O(1)。但在中间或开头插入、删除元素效率较低,因为需要移动后续元素,时间复杂度为 O(n)。

vector:需要频繁随机访问或尾部操作(如数据缓存、动态数组)

list 是双向链表,元素在内存中不连续存储。不支持随机访问,访问元素需要从头或尾开始遍历,时间复杂度为 O(n)。但在任意位置插入、删除元素效率较高,时间复杂度为 O(1)。

list 需要频繁在任意位置插入/删除(如LRU链表、需要稳定迭代器的场景)

2、setmap的主要用途是什么?

  • set 关联容器,用于存储唯一的元素,并且会对元素进行自动排序(默认按升序)。主要用于需要快速查找元素是否存在的场景,插入、删除和查找操作的时间复杂度均为 O(logn)。
  • map 关联容器,它存储的是键-值对,键是唯一的,并且会根据键进行排序。主要用于需要根据键快速查找对应值的场景,插入、删除和查找操作的时间复杂度同样为 O(logn)。

3、mapset的底层实现是什么?为什么?

  • 底层实现:红黑树(自平衡二叉搜索树)。
  • 原因:红黑树保证插入、删除、查找的时间复杂度为O(log n),且自动维护元素有序性。

如果问你红黑树的细节,你直接回答不了解。如果坚持让你回答,那就是在劝退你,也别浪费时间了

二、进阶

1、deque相对于vectorlist有什么优势,适用于什么场景?

[C++面试] 关于deque-CSDN博客

  • deque 是双端队列,结合了 vector 和 list 的部分优点。它支持随机访问,虽然效率略低于 vector,但也能在O(1) 时间内访问元素。同时,在两端插入和删除元素的效率较高,时间复杂度为 O(1),但中间插入仍需O(n)。
  • 中间插入效率:与vector类似,都需要移动元素,但deque的块结构可能减少部分元素移动,实际性能需具体测试。
  • deque由多个固定大小的数组块(chunk)组成,通过中控器(指针数组)管理。

整体上,deque对于给定的索引,计算出所在的块和块内偏移量并访问元素的操作次数是固定的,不随元素数量的增加而增加,所以其随机访问的时间复杂度仍然是 O(1) ,不过因为多了定位块的操作,效率会略低于 vector

  • 当需要在容器两端频繁插入和删除元素,同时也需要随机访问元素时,deque 是一个不错的选择,例如实现队列或栈。

2、priority_queue的特点是什么,如何使用?

priority_queue 是优先队列,它是一种容器适配器,默认使用 vector 作为底层容器,并且使用大顶堆(最大元素位于堆顶)来实现。它的特点是可以在 \(O(log n)\) 的时间复杂度内插入元素和删除堆顶元素,并且可以在 \(O(1)\) 的时间复杂度内访问堆顶元素。

    std::priority_queue<int> pq;pq.push(3);pq.push(1);pq.push(2);

3、 为什么priority_queue默认用vector而不是deque作为底层容器?

  • 堆操作(如push_heappop_heap)需要随机访问,vector的连续内存访问更高效。
  • deque的复杂内存布局可能导致堆操作性能下降。

4、forward_listlist相比,有什么优缺点,使用时需要注意什么?

  • 优点forward_list 是单向链表,只支持单向遍历,内存开销更小,插入和删除操作的效率也更高,因为只需要维护一个指针。每个节点只有后向指针 。
  • 缺点:不支持反向遍历,访问元素只能从头开始依次向后遍历,并且没有 size() 成员函数,获取元素数量需要手动遍历。
  • 使用注意事项:由于 forward_list 没有 push_back() 方法,只能使用 push_front() 插入元素。在插入和删除元素时,需要注意迭代器的有效性,因为操作可能会使迭代器失效。
  • 场景forward_list:内存敏感场景(如嵌入式系统),且只需单向遍历(如哈希表冲突链表)。list:需要反向操作或双向迭代器(如某些中间节点删除需前驱指针)。

5、stack是容器吗?它的默认底层容器是什么? 

  • stack是容器适配器,不是独立容器。(概念考察)
  • 默认底层容器是deque(支持两端高效操作),也可用vectorlist

三、高阶

1、如何为自定义类型选择容器?例如存储Student对象,需要按学号快速查找。

需求分析(开放题,仅供参考)

  • 若需有序性且频繁查找:用map<int, Student>(学号为键)。
  • 若无需有序性但需更快查找:用unordered_map(哈希表,O(1)查找)。
  • 若需频繁插入/删除且有序性不重要:用vector+排序(或维护有序插入)。

2、vector的迭代器失效场景有哪些?如何避免?

[C++面试] vector 面试点总结-CSDN博客

    • 插入元素导致容量变化(内存重分配):所有迭代器失效。
    • 删除元素:被删位置后的迭代器失效。

    避免方法 

    • 预分配足够容量(reserve)减少重分配。
    • 插入/删除后重新获取迭代器。

    vector<bool>可能是个坑(见上述链接)

    • 标准规定vector<bool>使用位压缩存储,每个元素占1 bit,但行为类似引用而非普通bool
    • 陷阱:不能直接取元素地址,且迭代器行为异常(如无法修改*iter的值)

    3、map::operator[]map::insert的陷阱是什么? 

    3.1、operator[]:若键不存在,会插入一个默认值,可能导致意外内存增长。

    map<string, int> scores = {{"Alice", 90}, {"Bob", 85}};
    // 尝试读取不存在的键 "Charlie"
    int charlie_score = scores["Charlie"];  // 插入 {"Charlie", 0}

    用 find 替代 operator[] 进行安全查找: 

    auto it = scores.find("Charlie");
    if (it != scores.end()) {int charlie_score = it->second;
    } else {// 处理键不存在的情况
    }

    3.2、insert:若键已存在,不会覆盖原有值,而是保留原有值,并返回一个 pair<iterator, bool>,其中 bool 为 false。需用insert_or_assign(C++17)或先find再更新。

    map<string, int> scores = {{"Alice", 90}, {"Bob", 85}};
    // 尝试插入或更新 "Alice" 的分数
    scores.insert({"Alice", 95});  // 插入失败,原有值 90 保留
    // 输出结果
    cout << "Alice's score: " << scores["Alice"] << endl;  // 输出 90
    方法1:insert_or_assign(C++17)​
    • 若键存在,更新值;若不存在,插入新键值对。
    int main() {map<string, int> scores = {{"Alice", 90}, {"Bob", 85}};// 更新 "Alice" 的分数为 95scores.insert_or_assign("Alice", 95);  // 更新成功scores.insert_or_assign("Charlie", 80); // 插入新键值对
    }
    方法2:先 find 再更新
    auto it = scores.find("Alice");
    if (it != scores.end()) {it->second = 95;  // 直接修改迭代器指向的值
    } else {scores.insert({"Alice", 95});
    }
    方法3:operator[] + 赋值
    • 若确定键需要插入或更新,可直接用 operator[]
    scores["Alice"] = 95;  // 无论 "Alice" 是否存在,值都会被设为 95

    实际场景建议

    1. 只读访问:用 find 替代 operator[],避免意外插入。

    2. 需要插入或更新

      • C++17+:优先用 insert_or_assign

      • C++11:用 find 检查是否存在,再决定插入或更新。

    3. 明确需要覆盖:直接使用 operator[] = value

    4、如何高效合并两个有序vector? 

    • 方法1:先insertsort(时间复杂度高,O(n log n))。
    • 方法2:使用std::merge(时间复杂度O(n),需额外空间):
    vector<int> merged;
    merged.reserve(v1.size() + v2.size());
    merge(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(merged));

    总结:

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

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

    相关文章

    蓝桥杯每日一题

    丢失的雨伞 题目思路代码演示 题目 今天晚上本来想练习一下前缀和与差分 结果给我搜出来这题&#xff08;几乎没啥关系&#xff09;&#xff0c;我看半天有点思路但又下不了手哈哈&#xff0c;难受一批 在图书馆直接红温了 题目链接 思路 题目要求找到两个不重叠的区间&…

    校园安全用电怎么保障?防触电装置来帮您

    引言 随着教育设施的不断升级和校园用电需求的日益增长&#xff0c;校园电力系统的安全性和可靠性成为了学校管理的重要课题。三相智能安全配电装置作为一种电力管理设备&#xff0c;其在校园中的应用不仅能够提高电力系统的安全性&#xff0c;还能有效保障师生的用电安全&am…

    Matlab 汽车二自由度转弯模型

    1、内容简介 Matlab 187-汽车二自由度转弯模型 可以交流、咨询、答疑 2、内容说明 略 摘 要 本文前一部分提出了侧偏角和横摆角速度作为参数。描述了车辆运动的运动状态&#xff0c;其中文中使用的参考模型是二自由度汽车模型。汽车速度被认为是建立基于H.B.Pacejka的轮胎模…

    OpenCV计算摄影学(20)非真实感渲染之增强图像的细节函数detailEnhance()

    操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 此滤波器增强特定图像的细节。 cv::detailEnhance用于增强图像的细节&#xff0c;通过结合空间域和频率域的处理&#xff0c;提升图像中特定细节…

    Java面试八股—Redis篇

    一、Redis的使用场景 &#xff08;一&#xff09;缓存 1.Redis使用场景缓存 场景&#xff1a;缓存热点数据&#xff08;如用户信息、商品详情&#xff09;&#xff0c;减少数据库访问压力&#xff0c;提升响应速度。 2.缓存穿透 正常的访问是&#xff1a;根据ID查询文章&…

    2025-03-17 Unity 网络基础1——网络基本概念

    文章目录 1 网络1.1 局域网1.2 以太网1.3 城域网1.4 广域网1.5 互联网&#xff08;因特网&#xff09;1.6 万维网1.7 小结 2 IP 地址2.1 IP 地址2.2 端口号2.3 Mac 地址2.4 小结 3 客户端与服务端3.1 客户端3.2 服务端3.3 网络游戏中的客户端与服务端 1 网络 ​ 在没有网络之前…

    【工业现场总线】控制网络的主要特点是?OSI参考模型的分层是?

    目录 1、控制网络的主要特点&#xff1f; 2、网络拓扑结构的主要类型&#xff1f;其各自主要特点是什么&#xff1f; 3、网络的传输介质主要有什么&#xff1f; 4、网络传输介质的访问控制方式主要有哪些&#xff1f;其各自主要特点是什么&#xff1f; 5、OSI参考模型的分…

    微软开源神器OmniParser V2.0 介绍

    微软开源的OmniParser V2.0是一款基于纯视觉技术的GUI智能体解析工具&#xff0c;旨在将用户界面&#xff08;UI&#xff09;截图转换为结构化数据&#xff0c;从而实现对计算机屏幕上的可交互元素的高效识别和操控。这一工具通过结合先进的视觉解析技术和大型语言模型&#xf…

    用python代码将excel中的数据批量写入Json中的某个字段,生成新的Json文件

    需求 需求&#xff1a; 1.将execl文件中的A列赋值给json中的TrackId&#xff0c;B列赋值给json中的OId 要求 execl的每一行&#xff0c;对应json中的每一个OId json 如下&#xff1a; {"List": [{"BatchNumber": "181-{{var}}",// "Bat…

    实验篇| Nginx环境搭建-安全配置

    在前面的文章里&#xff0c;阿祥详细介绍了在 Windows 系统中安装 Nginx 服务器的具体操作步骤&#xff0c;感兴趣的朋友可以参考&#xff1a;实验篇 | Nginx 反向代理 - 7 层代理 。完成 Nginx 的安装只是搭建 Web 服务的第一步&#xff0c;为了保障服务器的稳定运行以及数据安…

    理解我们单片机拥有的资源

    目录 为什么要查询单片机拥有的资源 所以&#xff0c;去哪些地方可以找数据手册 一个例子&#xff1a;STM32F103C8T6 前言 本文章隶属于项目&#xff1a; Charliechen114514/BetterATK: This is a repo that helps rewrite STM32 Common Repositorieshttps://github.com/C…

    从零开始 | C语言基础刷题DAY3

    ❤个人主页&#xff1a;折枝寄北的博客 目录 1.打印3的倍数的数2.从大到小输出3. 打印素数4.打印闰年5.最大公约数 1.打印3的倍数的数 题目&#xff1a; 写一个代码打印1-100之间所有3的倍数的数字 代码&#xff1a; int main(){int i 0;for (i 1; i < 100; i){if (i % …

    Blender材质 - 层权重

    层权重 混合着色器 可以让 面朝向的一面显示一种材质 另一面显示另一种材质 就能实现挺不错的材质效果 移动视角 材质会跟着变化 有点类似虚幻的视差节点BumpOffset

    3个 Vue $set 的应用场景

    大家好&#xff0c;我是大澈&#xff01;一个喜欢结交朋友、喜欢编程技术和科技前沿的老程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;关注我&#xff0c;科技未来或许我能帮到你&#xff01; 在 Vue2 中&#xff0c;由于 Object.defineProperty 的限制&#…

    Flutter_学习记录_ ImagePicker拍照、录制视频、相册选择照片和视频、上传文件

    插件地址&#xff1a;https://pub.dev/packages/image_picker 添加插件 添加配置 android无需配置开箱即用&#xff0c;ios还需要配置info.plist <key>NSPhotoLibraryUsageDescription</key> <string>应用需要访问相册读取文件</string> <key>N…

    LeetCode 解题思路 19(Hot 100)

    解题思路&#xff08;递归&#xff09;&#xff1a; 终止条件&#xff1a; 若节点为空&#xff0c;返回深度0。递归步骤&#xff1a; 分别计算左子树和右子树的最大深度&#xff0c;取较大者并加1&#xff08;当前节点&#xff09;。 Java代码&#xff1a; class Solution {…

    如何启用 HTTPS 并配置免费的 SSL 证书

    引言 HTTPS 已成为现代网站安全性的基础要求。通过 SSL/TLS 证书对数据进行加密&#xff0c;不仅可以保护用户隐私&#xff0c;还能提升搜索引擎排名并增强用户信任。本指南将详细介绍如何通过 Lets Encrypt&#xff08;免费、自动化的证书颁发机构&#xff09;为您的网站启用…

    element-plus中Popconfirm气泡确认框组件的使用

    1、基本使用 从element-plus官网复制代码&#xff1a; <template><el-popconfirm title"Are you sure to delete this?"><template #reference><el-button>Delete</el-button></template></el-popconfirm> </template…

    软件需求分类、需求获取(高软46)

    系列文章目录 软件需求分类&#xff0c;需求获取 文章目录 系列文章目录前言一、软件需求二、获取需求三、真题总结 前言 本节讲明软件需求分类、需求获取的相关知识。 一、软件需求 二、获取需求 三、真题 总结 就是高软笔记&#xff0c;大佬请略过&#xff01;

    10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)

    1、结果 2、完整C代码 #include <sstream> #include <iomanip> #include <iostream> #include <vector> #include <random> #include <cmath> #include <functional> #include <osgViewer/viewer> #include <osgDB/Read…