C++STL细节,底层实现,面试题04
文章目录
- 19. STL
- 19.1. 序列容器
- 19.1.1. vector
- 19.1.1.1. 底层实现和特点
- 19.1.1.2. 常用函数
- 19.1.1.3. emplace_back() vs push_back()
- 19.1.2. array
- 19.1.2.1. 底层实现和特点
- 19.1.2.2. 常用函数
- 19.1.3. deque
- 19.1.3.1. 底层实现和特点
- 19.1.3.2. 常用函数
- 19.1.4 list
- 19.1.4.1. 底层实现和特点
- 19.1.4.2. 常用函数
- 19.2. 关联容器
- 19.2.1. map
- 19.2.1.1. 底层实现和特点
- 19.2.1.2. 常用函数
- 19.2.1.3. map vs unordered_map
- 19.2.2. set
- 19.2.2.1. 底层实现和特点
- 19.2.2.2. 常用函数
- 19.2.2.3. set vs unordered_set
- 19.2.3 自定义比较函数对象,来定义元素的比较方式。
- 19.3. 容器适配器
- 19.3.1 queue
- 19.3.1.1. 底层实现和特点
- 19.3.1.2. 常用函数
- 19.3.2 priority_queue
- 19.3.2.1. 底层实现和特点
- 19.3.2.2. 常用函数
- 19.3.3 stack
- 19.3.3.1. 底层实现和特点
- 19.3.3.2. 常用函数
19. STL
C++标准库容器,官方文档https://learn.microsoft.com/zh-cn/cpp/standard-library/stl-containers?view=msvc-170
19.1. 序列容器
可顺序访问元素。
19.1.1. vector
19.1.1.1. 底层实现和特点
- 底层实现为动态数组(使用数组指针),动态分配空间。连续内存空间,支持随机访问。
- 它通过下标访问元素,时间复杂度o(1)。
- 尾部插入和删除操作,时间复杂度o(1)。
- 其余部分插入和删除,需要移动元素,时间复杂度o(n)。
- 当内存空间不足时,会重新分配内存空间,扩充为原来的两倍,并拷贝原有数据。
- 应用场景:适用于需要随机访问或频繁在序列尾部进行操作的场景。
19.1.1.2. 常用函数
- front() 返回第一个元素的引用。
- back() 返回最后一个元素的引用。
- begin() 返回第一个元素的迭代器。
- end() 返回超过末尾迭代器。
- clear() 清空。
- empty() 判空。
- emplace_back() 将就地构造的元素添加到末尾。
- push_back() 将元素添加到末尾。
- pop_back() 删除末尾元素。
- erase(position),erase(first,end) 删除元素。
- insert(positon,value) 添加元素。
- swap()交换容器元素。
- resize(size),resize(size,value) 指定新的大小。
19.1.1.3. emplace_back() vs push_back()
-
emplace_back()的参数会使用forward<>完美转发给构造函数,然后在容器提供的位置就地构造。即只构造一次,如下图。

-
push_back()的参数作为右值传入,先构造元素,再移动到末尾,即先调用构造函数,然后调用移动构造函数,如下图。

-
【注意】 emplace_back()的参数 {1,2} 会自动转换成initializer_list并进行完美转发,但vector并没有initializer_list的构造函数,所以报错。
vector<pair<int, int>> v;v.push_back({1,2});v.emplace_back({1,2}); //报错
19.1.2. array
19.1.2.1. 底层实现和特点
- 底层实现为数组,固定大小。连续内存空间,支持随机访问。
19.1.2.2. 常用函数
- fill() 替换所有的元素。
- swap() 交换容器元素。
19.1.3. deque
19.1.3.1. 底层实现和特点
- 底层实现为中控器+缓冲区+迭代器。
- 中控器,将分段连续的内存空间链接起来,才能在逻辑上连续,支持随机访问。使用指针数组,存放缓存区的地址。
- 迭代器,四个指针。
- T* cur,指向缓冲区的当前元素。
- T* first,指向缓冲区的头。
- T* last,指向缓存区的尾(含备用空间)。
- T** node,指向管控中心,即缓冲区的标记位置。
- 双端队列,首尾两端进行动态增删。
- 相比vector和list,deque不适合遍历,因为每次访问元素,都要检查是否到达了内存片段的边界,造成了额外开销。
- 应用场景:适用于需要频繁在序列两端进行操作的场景。
19.1.3.2. 常用函数
- emplace_back() 将就地构造的元素添加到末尾。
- emplace_front() 将就地构造的元素添加到开头。
- push_back() 将元素添加到末尾。
- push_front() 将元素添加到开头。
- pop_back() 删除末尾元素。
- pop_front() 删除开头元素。
- swap() 交换容器元素。
19.1.4 list
19.1.4.1. 底层实现和特点
- 底层实现为双链表,动态分配内存。离散内存空间,不支持随机访问。
- 通过指针访问元素,需要遍历直至要访问的元素,时间复杂度o(n)。
- 支持在任意位置快速插入和删除操作,时间复杂度o(1)。
- 支持双向遍历。
- 内存空间的使用效率并不高,一来它存放在离散而非连续的内存空间;二来它需要消耗更多内存空间来保存元素之间的关联信息。
- 应用场景:适用于需要频繁在任意位置进行操作,但不需要随机访问的场景。
19.1.4.2. 常用函数
- emplace_back() 将就地构造的元素添加到末尾。
- emplace_front() 将就地构造的元素添加到开头。
- push_back() 将元素添加到末尾。
- push_front() 将元素添加到开头。
- pop_back() 删除末尾元素。
- pop_front() 删除开头元素。
- remove() 删除指定值。
- reverse() 反转元素。
- sort() 按升序排序,sort( greater<>() ) 按降序排序。
- swap() 交换容器元素。
- rbegin() 返回反向第一个元素的迭代器。
- rend() 返回反向超过末尾迭代器。
19.2. 关联容器
通过key访问元素。
19.2.1. map
19.2.1.1. 底层实现和特点
- 底层实现为红黑树,有序。
- 应用场景:适用于需要通过key快速查找value的场景。
19.2.1.2. 常用函数
- contains() (C++20)是否包含指定键的元素。
- count() 是否包含指定键的元素。
- emplace() 就地插入构造的元素,即不执行复制或移动操作。
- find() 返回指定键的迭代器。
- erase(key),erase(iter_position) 移除指定键或指定位置的元素。
- lower_bound() 返回键值等于或大于指定键的第一个元素的迭代器。
- upper_bound() 返回键值大于指定键的第一个元素的迭代器。
19.2.1.3. map vs unordered_map
- 底层实现为哈希表,无序。
- 应用场景:适用于需要通过key快速查找value的场景,但不关心key的顺序。
- unordered_map 直接访问元素的速度更快,尤其在大规模时,因为它通过直接计算key的哈希值来访问元素,时间复杂度o(1)。
- 但unordered_map 内存占用更高,因为底层的哈希表需要预分配足够的空间。
19.2.2. set
19.2.2.1. 底层实现和特点
- 底层实现为红黑树,有序。
- 元素自身就是key。
- 元素有唯一性,不允许出现重复的元素,且元素不可更改,但可以插入或删除。
- 应用场景:适用于需要快速查找和去重的场景。
19.2.2.2. 常用函数
- contains() (C++20)是否包含指定键的元素。
- count() 是否包含指定键的元素。
- emplace() 就地插入构造的元素,即不执行复制或移动操作。
- find() 返回指定键的迭代器。
- erase(key),erase(iter_position) 移除指定键或指定位置的元素。
- lower_bound() 返回键值等于或大于指定键的第一个元素的迭代器。
- upper_bound() 返回键值大于指定键的第一个元素的迭代器。
19.2.2.3. set vs unordered_set
- 底层实现为哈希表,无序。
- 应用场景:适用于需要快速查找和去重的场景,但不关心元素的顺序。
- unordered_set 直接访问元素的速度更快,尤其在大规模时,因为它通过直接计算key的哈希值来访问元素,时间复杂度o(1)。
- 但unordered_set 内存占用更高,因为底层的哈希表需要预分配足够的空间。
19.2.3 自定义比较函数对象,来定义元素的比较方式。
#include<iostream>
#include<set>
using namespace std;// 自定义比较函数对象,按照 pair 的第二个值进行比较
struct CompareBySecond {bool operator()(const pair<int, int>& p1, const pair<int, int>& p2) const {return p1.second < p2.second;}
};int main()
{set<pair<int, int>, CompareBySecond> s = { {1,20},{2,10},{3,30},{4,5} };for (auto&& u : s)cout << u.first << " " << u.second << endl;return 0;
}
19.3. 容器适配器
本身只是一个封装层,必须依赖指定的底层容器,才能实现具体功能。即它是序列容器或关联容器的变体。
19.3.1 queue
19.3.1.1. 底层实现和特点
- 底层容器默认deque。
- 队列,先进先出。
- 应用场景:适用于需要先进先出操作的场景,如广度优先搜索、任务调度、数据缓冲区等。
19.3.1.2. 常用函数
- front() 返回第一个元素的引用。
- back() 返回最后一个元素的引用。
- empty() 返回是否空。
- pop() 头部移除元素。
- push() 尾部添加元素。
- size() 返回元素数量。
19.3.2 priority_queue
19.3.2.1. 底层实现和特点
- 底层容器默认vector。
- 优先队列,元素按照优先级排序,每次弹出最高优先级的元素,即默认最大堆。
- 最小堆使用 greater<> 作比较器。
- 应用场景:适用于需要按照优先级处理元素的场景,如任务调度、最大(小)堆实现等。
19.3.2.2. 常用函数
- top() 返回顶部元素的常量引用,即返回值不是左值。
- empty() 返回是否空。
- pop() 顶部移除元素,即弹出最大元素。
- push() 添加元素。
- size() 返回元素数量。
19.3.3 stack
19.3.3.1. 底层实现和特点
- 底层容器默认deque。
- 栈,后进先出。
- 不允许遍历,只能访问顶部元素。
- 应用场景:适用于需要后进先出操作的场景,如深度优先搜索、表达式求值、括号配对等。
19.3.3.2. 常用函数
- top() 返回顶部元素的引用。
- empty() 返回是否空。
- pop() 顶部移除元素。
- push() 顶部添加元素。
- size() 返回元素数量。
相关文章:
C++STL细节,底层实现,面试题04
文章目录 19. STL19.1. 序列容器19.1.1. vector19.1.1.1. 底层实现和特点19.1.1.2. 常用函数19.1.1.3. emplace_back() vs push_back() 19.1.2. array19.1.2.1. 底层实现和特点19.1.2.2. 常用函数 19.1.3. deque19.1.3.1. 底层实现和特点19.1.3.2. 常用函数 19.1.4 list19.1.4.…...
Linux查看Oracle数据库的环境变量
Linux查看Oracle数据库的环境变量 在Linux上查看Oracle数据库的环境变量,通常涉及检查当前shell会话中已设置的环境变量。这些环境变量可能包括ORACLE_HOME、ORACLE_SID、PATH(可能包含Oracle二进制文件的路径)等。 以下是几种方法来查看这…...
pg数据库学习知识要点分析-1
知识要点1 对象标识OID 在PostgreSQL内部,所有的数据库对象都通过相应的对象标识符(object identifier,oid)进行管理,这些标识符是无符号的4字节整型。数据库对象与相应oid 之间的关系存储在对应的系统目录中…...
【Web】CTFSHOW 七夕杯 题解
目录 web签到 easy_calc easy_cmd web签到 CTF中字符长度限制下的命令执行 rce(7字符5字符4字符)汇总_ctf中字符长度限制下的命令执行 5个字符-CSDN博客7长度限制直接梭了 也可以打临时文件RCE import requestsurl "http://4ae13f1e-8e42-4afa-a6a6-1076acd08211.c…...
react native 设置屏幕锁定
原生配置 android 在android/app/src/main/AndroidManifest.xml在这个文件里的入口activity里添加 android:screenOrientation"portrait" <activityandroid:name".MainActivity"android:label"string/app_name" …...
探索 IPv6 协议:互联网的新一代寻址
目录 一.概述 IPv4 的问题和 IPv6 的新特性 IPv6 协议体系 二.IPv6 寻址架构:巨大的地址空间与灵活的寻址模式 IPv6 寻址概述 地址表示方法 地址前缀与地址类型标识 单播地址 任播地址 多播地址 特殊的 IPv6 地址 IPv6 主机与路由器寻址 地址分配 三.I…...
Ubuntu意外断电vmdk损坏--打不开磁盘“***.vmdk”或它所依赖的某个快照磁盘。
背景:电脑资源管理器崩溃卡死,强行断电重启,结果虚拟机打不开了,提示打不开磁盘“***.vmdk”或它所依赖的某个快照磁盘。 删除lck文件:失败vmware-vdiskmanager修复 :提示无法修复最终用 VMFS Recovery挂载…...
202466读书笔记|《一天一首古诗词》——借问梅花何处落,风吹一夜满关山
202466读书笔记|《一天一首古诗词》——借问梅花何处落,风吹一夜满关山 上册下册 《一天一首古诗词》作者李锡琴,蛮早前加入书架的已购买书籍,这次刚好有点时间,利用起来读完。 赏析没有细看,只读了诗词部分࿰…...
如何调用本地ollama的http请求接口
http://127.0.0.1:11434/api/generate 使用http post请求,参数 { "model": "qwen", "prompt": "为什么天空是蓝色?", "stream": false } 返回结果如下: {"model": "qwen",…...
【C】190 颠倒二进制位
颠倒给定的 32 位无符号整数的二进制位。 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因…...
蓝桥杯备战5.图书管理员
[NOIP2017]图书管理员 (nowcoder.com) #include<bits/stdc.h> #define endl \n #define int long long using namespace std; const int N 2e510,M1e310; int a[N]; int n,q; int check(int l,int x) {int tmppow(10,l);for(int i1;i<n;i){if(a[i]%tmpx){cout<&…...
微型显示器可以实时监测大脑活动
美国团队开发基于LED的设备,以可视化大脑活动,在脑外科手术中指导神经外科医生 来自加州大学圣地亚哥分校和马萨诸塞州总医院的工程师和医生开发了一种薄膜显示设备,该设备结合了电极网格和特殊的GaN LED,可以在手术过程中实时跟…...
移动端适配方案
移动端适配 方案 1:rem html font-size 方案 2:vw rem html font-size rem 是相对于 html 元素的 font-size 来设置的单位,通过在不同屏幕尺寸下动态修改 html 元素的 font-size 可达到适配效果 在开发中,我们只需要考虑两个…...
【Ajax零基础教程】-----第一课 Ajax简介
一、什么是ajax ajax即 Asynchronous javascript And XML (异步 javaScript 和 XML) 是一种创建交互式,快速动态应用的网页开发技术,无需重新加载整个网页的情况下,能够更新页面局部数据的技术。 二、为什么使用Ajax 通过在后台与服务器进行少…...
大型医疗挂号微服务“马上好医”医疗项目(5)Swagger的使用
Swagger的简单介绍 Swagger 是一个 RESTful 接口文档的规范和工具集,它的目标是统一 RESTful 接口文档的格式和规范。在开发过程中,接口文档是非常重要的一环,它不仅方便开发者查看和理解接口的功能和参数,还能帮助前后端开发协同…...
C语言从头学04——介绍占位符和输出格式
占位符、输出格式都是与 printf() 相关的,当然其它函数也有用到占位符的。这里先介绍它们在 printf() 的使用。 一、先介绍占位符,所谓“占位符”通俗讲就是先占个位置,后边再找具体值(参数)代入进行显示的一种方法。先用一个例子说明…...
写爬虫代码抓取Asterank中小行星数据
2024年5月4日 问题来源 解决方案 回顾2023年7月14日自己写的爬虫代码 import requests import re import pandas as pd texts[] def getData(page):#每页评论的网址urlhttps://item.jd.com/51963318622.html#comment#添加headers,伪装成浏览器headers{User-Agent:…...
leetCode81. 搜索旋转排序数组 II
leetCode81. 搜索旋转排序数组 II 题目思路 可以二分后的具体思路见我的上篇博客 搜索旋转排序数组 代码 class Solution { public:bool search(vector<int>& nums, int target) {if(nums.empty()) return false;int R nums.size() - 1;while(R > 0 &&…...
在Ubuntu上怎么查看安装了哪些包?
2024年5月3日,周五晚上 在Ubuntu上,你可以使用以下命令来查看系统中已安装的包: 使用dpkg命令:dpkg --list这个命令将列出系统中所有已安装的软件包,包括名称、版本号和描述等信息。你可以使用 grep 命令来过滤结果&a…...
Navicat连接远程数据库时,隔一段时间不操作出现的卡顿问题
使用 Navicat 连接服务器上的数据库时,如果隔一段时间没有使用,再次点击就会出现卡顿的问题。 如:隔一段时间再查询完数据会出现: 2013 - Lost connection to MySQL server at waiting for initial communication packet, syste…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
