C++ STL 标准模板库
C++ STL 标准模板库
标准容器
顺序容器
vector
vector 向量容器
底层数据结构:动态开辟的数组,每次以原来空间大小的2倍进行扩容。采用allocator进行空间开辟和释放,对象创建和析构的分离。具体如C++模板学习笔记中简要实现C++中的vector。
增加:push_back、insert。
删除:pop_back、erase。
查询:operator[]、iterator、find、for-each。注意连续insert和erase中出现的迭代器失效问题。
其他:size、empty、reserve(预留空间)、resize(扩容)、swap(两个容器进行元素替换)。
reserve函数是给容器预留空间,并不会进行容器填充,容器的空间元素大小size为原来的大小。
resize函数是给容器开辟指定大小的内存空间,会对容器中的值进行添加,如果容器内部的元素是int,那么默认添加的元素为0,容器的空间元素大小size为扩容后的大小。
deque
deque 双端队列机制
#define MAP_SIZE=2; #define QUE_SIZE=4096/sizeof(T);
底层数据结构是一个动态开辟的二维数组(类似于邻接表),一维数组从2开始,以2倍的方式进行扩容,每次扩容后,原来的第二维数组,从第一维数组的下标oldsize/2开始存放,上下行都预留相同的空行,方便deque首尾元素的添加。
增加:push_back、push_front、insert
删除:pop_back、pop_front、erase
查询:iterator(连续erase和insert考虑容器失效问题)
deque底层内存是不是连续的?并不是,deque的底层是动态开辟的二维数组,第二维上是连续的,第一维上是不连续的。
list
list 链表容器
底层数据结构是双向循环链表 pre-data-next
增加:push_back、push_front、insert
删除:pop_back、pop_front、erase
查询:iterator(连续erase和insert考虑容器失效问题)
vector和deque的区别
可以从以下角度进行分析:
- 底层数据结构。vector是连续的动态数组;deque是第二维连续的动态二维数组。
- 前中后插入的时间复杂度。vector前中后插入的时间分别是O(n)/O(n)/O(1),deque前中后插入的时间复杂度分别是O(1)/O(n)/O(1)。
- 对内存的使用效率。vector必须是连续的空间,而deque只需要第二维上是连续的就行。
- 中间进行insert或者erase,vector效率稍微高一点,因为vector底层内存是连续的,deque因为空间是不连续的,会涉及内存转化等情况。
vector和list的区别
可以从以下角度进行分析:
- 底层数据结构。vector是连续的数组;list的双向循环链表。
- 查找和增加、删除的时间复杂度。vector的增加和删除O(n),查询O(n),随机访问O(1);链表的增加和删除O(1)(可能需要涉及搜索时间,具体情况具体分析),查询O(n),随机访问O(n)。
容器适配器
适配器的基本概念:
1、适配器底层没有自己的数据结构,它是另外一个容器的封装,它的方法全部由底层依赖的容器进行实现。
2、没有实现自己的迭代器。
自定义实现的stack容器:
#include<iostream>
#include<deque>
using namespace std;template<typename T,typename Container=deque<T>>
class Stack
{
public:void push(T &val) { con.push_back(val); }void pop() { con.pop_back(); }T top() const { return con.back(); }private:Container con;
};
容器适配器主要有stack、queue、priority_queue。
stack
主要方法有:push、pop、top、empty、size等
主要特点:先进后出
采用deque实现
queue
主要方法有:push、pop、front、back、empty、size等
主要特点:先进先出
采用deque实现
priority_queue
主要方法和stack的方法一致:push、pop、top、empty、size等
主要特点:和queue的不同在于,优先级高的先出队,并不是先进先出。
采用vector实现
为什么stack和queue都采用deque实现?
- vector初始内存效率很低,默认是0-1-2-4-8- ···-2^n,而deque一开始就是4096/sizeof(T)。
- queue需要支持头尾插入,所以采用deque效率高。
- vector需要大量的连续的内存空间,而deque只需要分段的内存,当存在大量数据时,deque效率会高一点。
为什么priority_queue采用vector实现?
- priority_queue的是一种大根堆的结构,一般情况下都是在一段连续的空间或者内存上进行保存。而deque在一维上不是连续的,所以就会导致很难存储大根堆树。
关联容器
常用方法:insert(val)、iterator、erase(iterator)、erase(key)。还有find的方法,查找对应的元素。
无序关联容器
哈希链式表,增删查的时间复杂度为O(1),也需要注意迭代器失效的问题。set是无序的。
unordered_set
不会存储key值重复的元素
unordered_multiset
会存储key值重复的元素
unordered_set<int> set1;
for (int i = 0; i < 20;++i)
{set1.insert(rand() % 100 + 1);
}
cout << "size:" << set1.size() << endl;
cout << "count 15:" << set1.count(15) << endl;for (int i = 0; i < 50;i++)
{set1.insert(i);
}
auto it1 = set1.begin();
for (; it1 != set1.end();++it1)
{cout << *it1 << " ";
}
cout << endl;
unorder_map
不允许key重复,如果插入过程中会出现key重复情况,那么就会对原来key对应的value的进行替换。
unorder_multimap
允许key可以重复。
map的operator[]重载函数存在一个情况,在查询时key存在的情况下返回value,不存在的情况下会自动创建一个key和value(默认为空)。
有序关联容器
红黑树,增删查时间复杂度为O(log2n),采用树进行存储
set
multiset
map
multimap
迭代器
迭代器iterator,一般容器内部都包含了iterator。
iterator:普通正向迭代器。一般是begin()/end()。
const_iterator:常量正向迭代器,返回值只能使用,不能修改。operator*操作符重载返回的是常量 const T& operator*。
reverse_iterator:反向迭代器。和前面两个迭代器不同的是,一般是rbegin()/rend()。
const_reverse_iterator:常量反向迭代器。
#include<iostream>
#include<vector>
using namespace std;int main()
{vector<int> v = {2, 3, 4, 6, 9, 8, 4, 2, 4, 5};auto it = v.begin();for (; it != v.end();++it){cout << *it << " ";// *it = 10;//普通正向迭代器可以修改其值}cout << endl;vector<int>::const_iterator c_it = v.begin();for (; c_it != v.end(); ++c_it){cout << *c_it << " ";// *c_it = 10;//常量正向迭代器无法修改其值}cout << endl;vector<int>::reverse_iterator r_it = v.rbegin();//获取最后一个元素的迭代器for (; r_it != v.rend();++r_it){cout << *r_it << " ";// *r_it = 10;//可以修改其值}cout << endl;vector<int>::const_reverse_iterator cr_it = v.rbegin();for (; cr_it != v.rend();++cr_it){cout << *cr_it << " ";}cout << endl;return 0;
}
函数对象
通过函数指针调用函数,是没有办法内联的,效率很低,因为有函数调用的开销
C++的函数对象,实现了operator()操作符重载
通过函数对象调用operator(),可以省略函数调用的开销,比通过函数指针调用函数(不能用内敛调用),效率更高。
函数对象是用类生成的,所以可以添加许多相关的成员变量,用来记录函数对象调用使用的更多信息。
函数调用类似于C语言的函数指针。
using关键字,对函数更改名字,类似于as方法。
#include<iostream>
using namespace std;template <typename T>
class greater2
{public:bool operator()(T&x,T&y)//二元函数对象{return x > y;}
};
template<typename T>
bool greater1(T&x,T&y)
{return x > y;
}
template<typename T,typename Compare>
bool compare(T x,T y,Compare comp)
{//Compare其实就是调用的对象或者函数实现内部功能return comp(x, y);
}
int main()
{//函数调用实现comparecout << compare<int>(10, 20, greater1<int>) << endl;//对象调用实现comparecout << compare<char>('a', 'c', greater2<char>()) << endl;return 0;
}
泛型算法
C++泛型算法都放在#include<algorithm>头文件内部。常见的泛型算法有sort、find、find_if、count、for_each、binary_search等
泛型算法的特点:
- 泛型算法的参数接收的都是迭代器。
- 泛型算法的参数还可以接收函数对象(C语言函数指针)。
int arr[] = {10, 20, 30, 34, 21, 12, 35, 32, 11, 22};
vector<int> vec(arr, arr + sizeof(arr) / sizeof(arr[0]));for(auto i:vec)
{cout << i << " ";
}
cout << endl;sort(vec.begin(), vec.end());for (auto i : vec)
{cout << i << " ";
}
cout << endl;if(binary_search(vec.begin(), vec.end(), 22))
{cout << "22 is existed" << endl;
}
else
{cout << "22 isn't existed" << endl;
}//传入函数对象greater,改变容器的排序方式的比较方式
sort(vec.begin(), vec.end(), greater<int>());
for (auto i : vec)
{cout << i << " ";
}
cout << endl;
绑定器 + 二元函数对象 -> 一元函数对象
绑定器存在C++的#include<functional>头文件中。
bind1st:把二元函数对象的operator()的第一个形参进行绑定起来。
bind2nd:把二元函数对象的operator()的第二个形参进行绑定起来。
//find_if是查找一个元素,需要一个一元函数对象
//查找第一个小于31的元素,并将其插入到其前面,greate a>b a=31
auto it2 = find_if(vec.begin(), vec.end(), bind1st(greater<int>(),31));
vec.insert(it2, 31);for (auto i : vec)
{cout << i << " ";
}
cout << endl;//在第一个小于19的前面插入19 a<b b=19
auto it3 = find_if(vec.begin(), vec.end(), bind2nd(less<int>(), 19));
vec.insert(it3, 19);for (auto i : vec)
{cout << i << " ";
}
cout << endl;
lambda表达式,类似于函数对象[](形参列表)->函数返回值{函数体}。
相关文章:
C++ STL 标准模板库
C STL 标准模板库 标准容器 顺序容器 vector vector 向量容器 底层数据结构:动态开辟的数组,每次以原来空间大小的2倍进行扩容。采用allocator进行空间开辟和释放,对象创建和析构的分离。具体如C模板学习笔记中简要实现C中的vector。 增…...
C#-集合小例子
目录 背景: 过程: 1.添加1-100数: 2.求和: 3.平均值: 4.代码: 总结: 背景: 往集合里面添加100个数,首先得有ArrayList导入命名空间,这个例子分为3步,1.添加1-100个数2.进行1-100之间的总和3.求总和的平均值&…...
git保存删除的文件
查看pg源码的函数具体内容: https://doxygen.postgresql.org/resowner_8h.html#a7f01c9e9f97849f2859feabd913de1f8 git add 添加了多余文件 git add . 表示当前目录所有文件,不小心就会提交其他文件 git add 如果添加了错误的文件的话 撤销操作 g…...
【golang】go语句执行规则(goroutine)(下)
怎样才能让主goroutine等待其他goroutine? 上篇文章提到,一旦主 goroutine 中的代码执行完毕,当前的 Go 程序就会结束运行,无论其他的 goroutine 是否已经在运行了。那么,怎样才能做到等其他的 goroutine 运行完毕之后…...
websocket 接收消息无法获取用户id
1.遇到问题 公司项目是基于ruoyi 框架快速搭建开发,使用多线程搜索查询,所以以用户区分任务,保证可以搜索任务和取消搜索,所以我这需要获得用户id,使用 SecurityUtils 共工工具类从请求头获取token,然后解…...
springboot通过sharding-dbc按年、月分片
目录 springboot通过sharding-dbc按年、月分片 1、引入pom依赖 2、application.yml配置 3、分片算法 4、注意事项 1、引入pom依赖 <!--shardingjdbc分片,和Druid不兼容,如果不使用sharding则需要注释--><dependency><groupId>org.…...
基于静电放电算法优化的BP神经网络(预测应用) - 附代码
基于静电放电算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于静电放电算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.静电放电优化BP神经网络2.1 BP神经网络参数设置2.2 静电放电算法应用 4.测试结果:5…...
开发者插件推荐FeHelper
开发者巨好用的插件、有很多功能比如json美化、对比,二维码/解码,图片转Base64,时间戳转换等 一、下载插件 1、打开网址:FeHelper - Awesome(建议用谷歌打开); 2、选择要下载的版本,…...
【MySQL】JSON 格式字段处理
MySQL 5.7 版本后已支持 JSON 格式,这虽是 MySQL 的一小步,但可以说是程序开发的一大步,再也不用将 JSON 内容塞到 VARCHAR 类型字段了,程序设计也会变得更加灵活。网上大多只针对JSONObject 对象类型,本文也将详解 JS…...
数据库选型<1>
数据库选型 1.SQL与NoSQL1.SQL2.NoSQL 2.各种数据存储的适应场景1.MySQL 3.构建MySQL开发环境 1.SQL与NoSQL 1.SQL 关系型数据库 MySQLOracleSQL serverPostGreSQL 关系型数据库的特点 数据结构化存储在二维表中(新增JSON存储方式,也有nosql的特点)支持事务的原子…...
1.Flink源码编译
目录 1.环境版本 1.1 jdk 1.2.maven 1.3.node 1.4.scala 2.下载flink源码 3.编译源码 4.idea打开flink源码 5.运行wordcount 1.环境版本 软件地址 链接:https://pan.baidu.com/s/1ZxYydR8rBfpLCcIdaOzxVg 提取码:12xq 1.1 jdk 1.2 maven 1.…...
Linux内核数据结构 散列表
1、散列表数据结构 在Linux内核中,散列表(哈希表)使用非常广泛。本文将对其数据结构和核心函数进行分析。和散列表相关的数据结构有两个:hlist_head 和 hlist_node //hash桶的头结点 struct hlist_head {struct hlist_node *first…...
数据库系统课设——基于python+pyqt5+mysql的酒店管理系统(可直接运行)--GUI编程
几个月之前写的一个项目,通过这个项目,你能学到关于数据库的触发器知识,python的基本语法,python一些第三方库的使用,包括python如何将前后端连接起来(界面和数据),还有界面的设计等…...
《C和指针》笔记9: typedef
C语言支持一种叫作typedef的机制,它允许你为各种数据类型定义新名字。typedef声明的写法和普通的声明基本相同,只是把typedef这个关键字出现在声明的前面。例如,下面这个声明: char *ptr_to_char;把变量ptr_to_char声明为一个指向…...
《C和指针》笔记6:gets/puts/scanf/printf/getchar函数用法
本博客可以了解一些gets/puts/scanf/printf/getchar函数的基本用法。 文章目录 1. gets函数2. puts函数3. scanf函数4. printf函数5. getchar函数6. putchar函数 1. gets函数 gets函数从标准输入读取一行文本并把它存储于作为参数传递给它的数组中。一行输入由一串字符组成&a…...
智慧课堂学生行为检测评估算法
智慧课堂学生行为检测评估算法通过yolov5系列图像识别和行为分析,智慧课堂学生行为检测评估算法评估学生的表情、是否交头接耳行为、课堂参与度以及互动质量,并提供相应的反馈和建议。智慧课堂学生行为检测评估算法能够实时监测学生的上课行为࿰…...
rainbond云原生应用管理平台部署
rainbond简介 rainbond 是 一个 开源的Kubernetes 云原生应用管理平台。 Rainbond 核心100%开源,Serverless体验,不需要懂K8s也能轻松管理容器化应用,平滑无缝过渡到K8s,是国内首个支持国产化信创、适合私有部署的一体化应用管理…...
jemter连接数据json断言
文章目录 一、jmeter连接数据库1、加载JDBC驱动2、连接数据3、SQL Query的Query Type使用方法:4、Variable Name使用方法:5、Result variable name使用方法: 二、Json响应断言1、添加 》 断言 》 JSON断言2、JSON断言界面参数说明:…...
JavaFX 加载 fxml 文件
JavaFX 加载 fxml 文件主要有两种方式,第一种方式通过 FXMLLoader 类直接加载 fxml 文件,简单直接,但是有些控件目前还不知道该如何获取,所以只能显示,目前无法处理。第二种方式较为复杂,但是可以使用与 fx…...
(三)Redis——Set
SADD key value SMEMBERS 127.0.0.1:6379> SADD set aaa 1 127.0.0.1:6379> SMEMBERS set aaa 127.0.0.1:6379> SADD set aaa 0 127.0.0.1:6379> SMEMBERS set aaaSISMEMBER 判断 aaa 是否在 set 中 127.0.0.1:6379> SISMEMBER set aaa 1 127.0.0.1:6379>…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
