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

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数据库的环境变量&#xff0c;通常涉及检查当前shell会话中已设置的环境变量。这些环境变量可能包括ORACLE_HOME、ORACLE_SID、PATH&#xff08;可能包含Oracle二进制文件的路径&#xff09;等。 以下是几种方法来查看这…...

pg数据库学习知识要点分析-1

知识要点1 对象标识OID 在PostgreSQL内部&#xff0c;所有的数据库对象都通过相应的对象标识符&#xff08;object identifier&#xff0c;oid&#xff09;进行管理&#xff0c;这些标识符是无符号的4字节整型。数据库对象与相应oid 之间的关系存储在对应的系统目录中&#xf…...

【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 寻址架构&#xff1a;巨大的地址空间与灵活的寻址模式 IPv6 寻址概述 地址表示方法 地址前缀与地址类型标识 单播地址 任播地址 多播地址 特殊的 IPv6 地址 IPv6 主机与路由器寻址 地址分配 三.I…...

Ubuntu意外断电vmdk损坏--打不开磁盘“***.vmdk”或它所依赖的某个快照磁盘。

背景&#xff1a;电脑资源管理器崩溃卡死&#xff0c;强行断电重启&#xff0c;结果虚拟机打不开了&#xff0c;提示打不开磁盘“***.vmdk”或它所依赖的某个快照磁盘。 删除lck文件&#xff1a;失败vmware-vdiskmanager修复 &#xff1a;提示无法修复最终用 VMFS Recovery挂载…...

202466读书笔记|《一天一首古诗词》——借问梅花何处落,风吹一夜满关山

202466读书笔记|《一天一首古诗词》——借问梅花何处落&#xff0c;风吹一夜满关山 上册下册 《一天一首古诗词》作者李锡琴&#xff0c;蛮早前加入书架的已购买书籍&#xff0c;这次刚好有点时间&#xff0c;利用起来读完。 赏析没有细看&#xff0c;只读了诗词部分&#xff0…...

如何调用本地ollama的http请求接口

http://127.0.0.1:11434/api/generate 使用http post请求&#xff0c;参数 { "model": "qwen", "prompt": "为什么天空是蓝色?", "stream": false } 返回结果如下&#xff1a; {"model": "qwen",…...

【C】190 颠倒二进制位

颠倒给定的 32 位无符号整数的二进制位。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。在这种情况下&#xff0c;输入和输出都将被指定为有符号整数类型&#xff0c;并且不应影响您的实现&#xff0c;因…...

蓝桥杯备战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的设备&#xff0c;以可视化大脑活动&#xff0c;在脑外科手术中指导神经外科医生 来自加州大学圣地亚哥分校和马萨诸塞州总医院的工程师和医生开发了一种薄膜显示设备&#xff0c;该设备结合了电极网格和特殊的GaN LED&#xff0c;可以在手术过程中实时跟…...

移动端适配方案

移动端适配 方案 1&#xff1a;rem html font-size 方案 2&#xff1a;vw rem html font-size rem 是相对于 html 元素的 font-size 来设置的单位&#xff0c;通过在不同屏幕尺寸下动态修改 html 元素的 font-size 可达到适配效果 在开发中&#xff0c;我们只需要考虑两个…...

【Ajax零基础教程】-----第一课 Ajax简介

一、什么是ajax ajax即 Asynchronous javascript And XML (异步 javaScript 和 XML) 是一种创建交互式&#xff0c;快速动态应用的网页开发技术&#xff0c;无需重新加载整个网页的情况下&#xff0c;能够更新页面局部数据的技术。 二、为什么使用Ajax 通过在后台与服务器进行少…...

大型医疗挂号微服务“马上好医”医疗项目(5)Swagger的使用

Swagger的简单介绍 Swagger 是一个 RESTful 接口文档的规范和工具集&#xff0c;它的目标是统一 RESTful 接口文档的格式和规范。在开发过程中&#xff0c;接口文档是非常重要的一环&#xff0c;它不仅方便开发者查看和理解接口的功能和参数&#xff0c;还能帮助前后端开发协同…...

C语言从头学04——介绍占位符和输出格式

占位符、输出格式都是与 printf() 相关的&#xff0c;当然其它函数也有用到占位符的。这里先介绍它们在 printf() 的使用。 一、先介绍占位符&#xff0c;所谓“占位符”通俗讲就是先占个位置&#xff0c;后边再找具体值(参数)代入进行显示的一种方法。先用一个例子说明…...

写爬虫代码抓取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&#xff0c;伪装成浏览器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日&#xff0c;周五晚上 在Ubuntu上&#xff0c;你可以使用以下命令来查看系统中已安装的包&#xff1a; 使用dpkg命令&#xff1a;dpkg --list这个命令将列出系统中所有已安装的软件包&#xff0c;包括名称、版本号和描述等信息。你可以使用 grep 命令来过滤结果&a…...

Navicat连接远程数据库时,隔一段时间不操作出现的卡顿问题

使用 Navicat 连接服务器上的数据库时&#xff0c;如果隔一段时间没有使用&#xff0c;再次点击就会出现卡顿的问题。 如&#xff1a;隔一段时间再查询完数据会出现&#xff1a; 2013 - Lost connection to MySQL server at waiting for initial communication packet, syste…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...