全面解析 C++ STL 中的 set 和 map
C++ 标准模板库(STL)中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中,set
和 map
是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度,详细解读它们的设计与使用。
目录
1. 什么是关联式容器
关联式容器的核心特性
2. set 容器详解
2.1 基本概念与特性
2.2 底层实现:红黑树
红黑树的特性
红黑树的操作
2.3 构造函数
2.4 常用操作与复杂度分析
插入操作
查找操作
删除操作
遍历
2.5 特殊操作与技巧
(1) 自定义排序规则
(2) 范围删除
(3) 应用:求两个数组的交集
2.6 multiset 的区别与应用
1. 什么是关联式容器
关联式容器是一类根据关键字组织和管理数据的容器。与序列式容器(如 vector
和 list
)相比,关联式容器的主要区别如下:
特性 | 关联式容器(set /map ) | 序列式容器(vector /list ) |
---|---|---|
数据存储顺序 | 按关键字排序 | 按插入顺序 |
数据访问复杂度 | O(logN)O(\log N)O(logN) | O(1)O(1)O(1) 或 O(N)O(N)O(N) |
是否支持随机访问 | 否 | 是 |
是否支持按索引访问 | 否 | 是 |
关联式容器分为有序和无序两类:
- 有序容器:如
set
和map
,基于平衡二叉树(红黑树)实现,数据按排序规则组织。 - 无序容器:如
unordered_set
和unordered_map
,基于哈希表实现,提供更高效的查找速度,但不保证元素顺序。
关联式容器的核心特性
- 键值对:关联式容器通过关键字对元素进行组织,
set
中的关键字即为数据本身,而map
则以键值对形式存储数据。 - 自动排序:有序容器会自动对数据进行排序(升序或自定义规则)。
- 高效操作:插入、删除、查找的平均时间复杂度为 O(logN)O(\log N)O(logN)(红黑树实现)。
2. set
容器详解
2.1 基本概念与特性
set
是一种集合数据结构,用于存储唯一且自动排序的元素。它的主要特点如下:
- 数据唯一性:同一元素不能重复插入。
- 自动排序:默认按升序排序,可通过自定义比较器更改排序规则。
- 迭代器类型:
set
支持双向迭代器,不支持随机访问。 - 底层实现:使用红黑树作为存储结构。
2.2 底层实现:红黑树
红黑树的特性
红黑树是一种平衡二叉搜索树,满足以下性质:
- 每个节点是红色或黑色。
- 根节点是黑色。
- 每个叶子节点(
nullptr
或 NIL 节点)是黑色。 - 如果一个节点是红色,则其子节点必须是黑色(即红色节点不能相邻)。
- 从任意节点到其每个叶子节点的路径都包含相同数量的黑色节点。
红黑树的操作
- 插入:通过旋转和重新着色,确保平衡性和红黑性质。
- 删除:比插入更复杂,同样通过旋转和着色维护树的性质。
- 查找:沿树遍历,时间复杂度为 O(logN)O(\log N)O(logN)。
在 set
和 map
中,红黑树用来高效实现元素的有序存储和快速查找。
2.3 构造函数
set
提供以下几种构造方式:
- 默认构造:创建一个空集合。
set<int> s;
- 初始化列表构造:直接用
{}
初始化集合。set<int> s = {3, 1, 4, 1, 5, 9}; // 重复元素自动去重
- 迭代器区间构造:从其他容器的元素构造集合。
vector<int> v = {1, 2, 3, 4}; set<int> s(v.begin(), v.end());
- 自定义比较规则:
set<int, greater<int>> s = {3, 1, 4}; // 按降序排序
2.4 常用操作与复杂度分析
操作 | 函数 | 复杂度 | 说明 |
---|---|---|---|
插入 | insert(value) | O(logN)O(\log N)O(logN) | 插入元素,若已存在则插入失败 |
删除 | erase(value) | O(logN)O(\log N)O(logN) | 删除指定元素 |
查找 | find(value) | O(logN)O(\log N)O(logN) | 返回迭代器,指向目标元素 |
统计 | count(value) | O(logN)O(\log N)O(logN) | 判断元素是否存在,结果为 0 或 1 |
遍历 | begin(), end() | O(N)O(N)O(N) | 正向迭代访问所有元素 |
下界/上界 | lower_bound()/upper_bound() | O(logN)O(\log N)O(logN) | 返回 >= / > 某值的第一个元素的迭代器 |
插入操作
set<int> s;
auto res = s.insert(10); // 插入 10
if (res.second) {cout << "插入成功" << endl;
} else {cout << "插入失败" << endl;
}
查找操作
if (s.find(20) != s.end()) {cout << "找到元素 20" << endl;
}
删除操作
s.erase(10); // 删除值为 10 的元素
遍历
for (int x : s) {cout << x << " "; // 正向遍历
}
for (auto it = s.rbegin(); it != s.rend(); ++it) {cout << *it << " "; // 反向遍历
}
2.5 特殊操作与技巧
(1) 自定义排序规则
set
默认按升序排序,使用仿函数或 std::greater
可修改排序规则:
set<int, greater<int>> s = {3, 1, 4};
(2) 范围删除
删除值在 [low, high)
范围内的所有元素:
s.erase(s.lower_bound(10), s.upper_bound(50));
(3) 应用:求两个数组的交集
vector<int> intersection(const vector<int>& nums1, const vector<int>& nums2) {set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());vector<int> result;for (int x : s1) {if (s2.count(x)) result.push_back(x);}return result;
}
2.6 multiset
的区别与应用
multiset
与 set
的区别在于:
multiset
允许存储重复元素。- 插入、删除和查找操作的接口与
set
相同,但返回的结果会包含重复项。
multiset<int> ms = {1, 2, 2, 3};
ms.insert(2); // 再次插入 2
3. map
容器详解
3.1 基本概念与特性
map
是一个关联式容器,用于存储键值对(key-value
)。与 set
相比,map
不仅存储键(key
),还存储与每个键关联的值(value
)。map
的主要特点包括:
- 键唯一性:每个键在
map
中都是唯一的。 - 自动排序:默认按照键的升序排序,也可以通过自定义比较器来更改排序规则。
- 底层实现:基于红黑树实现,操作复杂度为 O(logN)O(\log N)O(logN)。
- 支持随机访问:与
set
不同,map
中存储的键值对支持通过键快速查找对应的值。
map<int, string> m;
m[1] = "apple"; // 插入键值对 (1, "apple")
m[2] = "banana"; // 插入键值对 (2, "banana")
m[3] = "cherry"; // 插入键值对 (3, "cherry")
内部存储结构
map
使用红黑树存储数据,保证了所有元素按键值自动排序。在 map
中,每个节点存储一个 pair<const Key, T>
,其中 const Key
表示键,T
表示值。红黑树的特点确保了查找、插入和删除操作的时间复杂度都为 O(logN)O(\log N)O(logN)。
3.2 构造与初始化
map
提供了多种构造方法,以适应不同的使用场景:
-
默认构造:创建一个空
map
。map<int, string> m;
-
初始化列表构造:通过初始化列表直接创建
map
。map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
-
范围构造:从另一个容器(如
set
、vector
等)构造map
。vector<pair<int, string>> v = {{1, "apple"}, {2, "banana"}}; map<int, string> m(v.begin(), v.end());
-
自定义比较器:通过传入自定义比较器,指定键的排序方式。
map<int, string, greater<int>> m; // 降序排序 m[2] = "banana"; m[1] = "apple";
3.3 常用操作与复杂度分析
操作 | 函数 | 复杂度 | 说明 |
---|---|---|---|
插入 | insert(pair) | O(logN)O(\log N)O(logN) | 插入一个键值对,若已存在则插入失败 |
插入或修改 | operator[] | O(logN)O(\log N)O(logN) | 插入新元素或修改已有元素的值 |
查找 | find(key) | O(logN)O(\log N)O(logN) | 查找指定键,返回键值对的迭代器 |
统计 | count(key) | O(logN)O(\log N)O(logN) | 查找指定键是否存在(map 中为 0 或 1) |
删除 | erase(key) | O(logN)O(\log N)O(logN) | 删除指定键及其对应的值 |
遍历 | begin(), end() | O(N)O(N)O(N) | 正向遍历所有元素 |
下界/上界 | lower_bound(key) /upper_bound(key) | O(logN)O(\log N)O(logN) | 查找大于等于某值或大于某值的第一个元素 |
插入与查找操作
-
插入:可以通过
insert
方法插入新的键值对,也可以通过operator[]
插入或修改键值对。map<int, string> m; m.insert({1, "apple"}); m[2] = "banana"; // 插入或修改
-
查找:
find
方法返回一个迭代器,指向指定键的键值对,若未找到则返回end()
。auto it = m.find(1); if (it != m.end()) {cout << "Found: " << it->second << endl; // 输出 "apple" }
删除操作
删除某个键值对:
m.erase(1); // 删除键为 1 的元素
3.4 遍历与修改
map
提供了多种遍历方法:
-
范围 for:
for (const auto& [key, value] : m) {cout << key << ": " << value << endl; }
-
传统迭代器:
for (auto it = m.begin(); it != m.end(); ++it) {cout << it->first << ": " << it->second << endl; }
修改值
可以通过迭代器直接修改值,operator[]
也支持修改已有键的值:
m[2] = "grape"; // 修改键为 2 的值为 "grape"
auto it = m.find(2);
if (it != m.end()) {it->second = "orange"; // 通过迭代器修改值
}
3.5 特殊操作与进阶技巧
(1) 下界与上界
通过 lower_bound()
和 upper_bound()
方法,可以获取某个键的下界和上界,常用于区间查找。
lower_bound(key)
:返回第一个大于等于key
的元素。upper_bound(key)
:返回第一个大于key
的元素。
map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
auto lb = m.lower_bound(2); // 返回键为 2 或大于 2 的第一个元素
cout << lb->second << endl; // 输出 "banana"
(2) 自定义排序规则
如同 set
,map
也可以通过自定义比较器来实现不同的排序规则。
map<int, string, greater<int>> m = {{1, "apple"}, {3, "cherry"}, {2, "banana"}};
for (const auto& [key, value] : m) {cout << key << ": " << value << endl;
} // 输出:3: cherry 2: banana 1: apple
(3) 范围删除
删除某个键值范围内的元素,常用于清除一段区间:
map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
m.erase(m.lower_bound(2), m.upper_bound(3)); // 删除键为 2 和 3 的元素
3.6 multimap
的区别与应用
multimap
是 map
的扩展,允许相同的键有多个值(即支持键的冗余)。与 map
的区别在于,multimap
在插入重复键时不会丢失数据,而 map
会自动覆盖原有键。
multimap<int, string> mm;
mm.insert({1, "apple"});
mm.insert({1, "banana"});
mm.insert({2, "cherry"});for (const auto& [key, value] : mm) {cout << key << ": " << value << endl; // 输出:1: apple 1: banana 2: cherry
}
multimap
在某些场景下非常有用,例如存储学生成绩时,可能有多个学生取得相同的分数。
4. 高级案例:综合利用 set
和 map
4.1 查找两个数组的交集
vector<int> intersection(const vector<int>& nums1, const vector<int>& nums2) {set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());vector<int> result;for (int x : s1) {if (s2.count(x)) result.push_back(x);}return result;
}
4.2 构建词频统计表
map<string, int> wordCount(const vector<string>& words) {map<string, int> wordMap;for (const string& word : words) {wordMap[word]++;}return wordMap;
}
4.3 高效查找链表中的环
bool hasCycle(ListNode* head) {set<ListNode*> visited;while (head != nullptr) {if (visited.find(head) != visited.end()) {return true; // 找到环}visited.insert(head);head = head->next;}return false;
}
5. 性能优化与注意事项
5.1 使用 unordered_map
和 unordered_set
在很多查找密集型的应用中,unordered_map
和 unordered_set
基于哈希表实现,提供常数时间复杂度 O(1)O(1)O(1) 的查找和插入操作。它们的性能优势适用于不需要保持元素顺序的场景。
5.2 避免不必要的拷贝
当插入大量数据时,可以使用 emplace()
来避免不必要的对象拷贝。emplace()
可以直接构造元素,而无需创建临时对象。
map<int, string> m;
m.emplace(1, "apple"); // 不会发生拷贝
5.3 避免频繁修改键
map
不支持修改键,修改键会导致数据结构破坏。因此,避免频繁修改键,而应使用新的键值对进行插入和删除。
6. 总结
通过本文的详细解析,我们全面了解了 C++ 中 set
和 map
容器的使用、底层实现以及高效操作技巧。掌握这些基本知识后,开发者可以灵活使用 set
和 map
来处理各种复杂的关联数据问题,从而提高程序的效率和可读性。
在实际开发中,选择合适的容器(如 map
与 unordered_map
,set
与 unordered_set
)可以帮助我们应对不同的数据处理需求,避免性能瓶颈。希望通过本文的学习,你能够深入掌握这些强大的容器,提升 C++ 编程技能。
相关文章:
全面解析 C++ STL 中的 set 和 map
C 标准模板库(STL)中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中,set 和 map 是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度,详细…...
【RL Application】语义分割中的强化学习方法
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...
MySql:Centos7安装MySql
目录 安装之前,清除MySql残留文件 下载MySql的官方yum源 安装MySql 服务 MySql配置 常见问题 本次安装基于Centos7,平台为云服务器,由XShell软件演示。 注意,请将用户切换为Root用户。 安装之前,清除MySql残留文…...
数据结构-散列函数的构造方法
一.数字关键词 关键词存储应该尽可能的离散 直接定址法:利用线性函数,例如上面的例子,h(key)key-1990,key1990,这个就被存放在0的位置 数字分析法:关键字可能有很到位组成,每一位变化可能都不一样,有的位是不变的,就是说不同的对象这一位都是一样的,有的…...
MySQL:DDL数据定义语言
DDL(Data Definition Language),数据定义语言 对数据库的常用操作 查看所有数据库 语法:show databases; 创建数据库 dbname:用户自己定义的数据库名称。 语法:create database [if not exists] dbname [charsetutf8]; 切换…...
【落羽的落羽 C语言篇】指针·之其五
文章目录 一、冒泡排序二、qsort排序1. qsort使用指南2.回调函数3. qsort函数的模拟实现 一、冒泡排序 冒泡排序的核心思想就是:两两相邻的元素进行比较和交换。 现在,我们想编写一个函数,使它能够运用冒泡排序的原理,由小到大排…...
Java程序员最新场景面试题总结
上周,在与部门业务伙伴(BP)的交谈中,我了解到当前求职市场的一个显著现象:她在招聘平台上发布的初级后端岗位每日吸引了超过500份简历的投递。这一现象凸显了Java后端岗位竞争的激烈程度,尤其是在这个技术日…...
平衡性能与隐私:解读Google的服务器端标记
在当前数字化时代,企业需要深入洞察用户行为,以提高网站转化率。然而,随着用户对隐私保护的期待日益提高以及相关法规的收紧,如何兼顾性能与隐私成为了一大挑战。为了解决这一问题,Google推出了服务器端标记࿰…...
在云上怎么样让环境更加安全?
随着云计算的普及,越来越多的企业和组织将其应用迁移到云端。在这个过程中,安全性成为了一个不可忽视的重要因素。华为云作为全球领先的云服务提供商,致力于为用户提供安全可靠的云环境。本文九河云将探讨在华为云上如何增强环境的安全性。 …...
分布式实验一
Socket编程作业: 在Linux系统上,用C编两个程序:Client和Server。两个进程间利用socket进行TCP通信。 要求: Server进程运行后,输出本进程所在主机IP地址以及正在监听的端口号; Client进程运行后,…...
网络安全防护指南
网络安全防护指南 网络安全是指保护网络系统中的硬件、软件及数据不受偶然或恶意原因而遭到破坏、更改或泄露,确保网络系统连续可靠地正常运行。随着互联网的普及和技术的发展,网络安全问题日益严峻,对个人、企业和国家都构成了巨大威胁。因…...
DreamCamera2相机预览变形的处理
最近遇到一个问题,相机更换了摄像头后,发现人像角度顺时针旋转了90度,待人像角度正常后,发现 预览时图像有挤压变形,最终解决。在此记录 一人像角度的修改 先放示意图 设备预览人像角度如图1所示,顺时针旋…...
【Go 基础】channel
Go 基础 channel 什么是channel,为什么它可以做到线程安全 Go 的设计思想就是:不要通过共享内存来通信,而是通过通信来共享内存。 前者就是传统的加锁,后者就是 channel。也即,channel 的主要目的就是在多任务间传递…...
长安汽车嵌入式面试题及参考答案
数据结构中的堆栈和编程中的堆栈有什么区别? 在数据结构中,堆栈是一种抽象的数据类型。它遵循后进先出(LIFO)的原则。从操作角度来看,有入栈(push)和出栈(pop)操作。例如…...
理解Linux的select、poll 和 epoll:从原理到应用场景
I/O 多路复用并不是什么新东西,select 早在 1983 年就出现了,poll 在 1997 年,epoll 是 2002 年的产物。面试题总爱问“多路复用多厉害?”其实它就是把轮询的锅甩给了操作系统,而操作系统不过是用 CPU 指令帮你完成事件…...
(一)Linux下安装NVIDIA驱动(操作记录)
目录 一、查看CUDA版本 1.输入nvidia-smi,查看驱动支持的最大CUDA版本,这里是11.6 2.输入nvcc --version,查看当前安装的CUDA版本,这里是11.3 二、卸载旧的NVIDIA驱动 1.卸载原有驱动 2.禁用nouveau(必须&#x…...
二分法篇——于上下边界的扭转压缩间,窥见正解辉映之光(2)
前言 上篇介绍了二分法的相关原理并结合具体题目进行讲解运用,本篇将加大难度,进一步强化对二分法的掌握。 一. 寻找峰值 1.1 题目链接:https://leetcode.cn/problems/find-peak-element/description/ 1.2 题目分析: 题目要求返回数组内…...
移动机器人课程建图实验-ROSbug汇总
问题1描述 $ rosrun robot_state_publisher robot_state_publisher [ERROR] [1733131886.474757207]: [registerPublisher] Failed to contact master at [localhost:11311]. Retrying...解决方案 这个错误信息表明 robot_state_publisher 节点无法联系到 ROS master。通常&…...
记录vite关于tailwindcss4.0-bate4出现margin[m-*]、padding[p-*]无法生效的问题。
环境如下: vite:5.4.10 tailwindcss: 4.0.0-beta.4 tailwindcss/vite: 4.0.0-beta.4 4.0默认的样式优先级比较低 如果使用了一些reset的css文件 那么很多样式会失效 例如:reset.css中 html, body, ul, li, h1, h2, h3, h4, h5, h6, dl, dt, dd, ol, i…...
WPF+MVVM案例实战与特效(三十)- 封装一个系统日志显示控件
文章目录 1、运行效果2、日志控件封装1、文件创建2、DisplayLogPanel.xaml 代码3、DisplayLogPanel.cs 代码4、数据模型5、枚举类型3、自定义控件使用1、LogPanelWindow.xaml2、LogPanelViewModel.cs4、总结1、运行效果 2、日志控件封装 1、文件创建 打开 Wpf_Examples ,在 …...
redis中jedis和lettuce pool的区别,那个更好,使用范围更广
在 Redis 的 Java 客户端中,Jedis 和 Lettuce 是两种最常用的客户端库,它们都支持连接池(JedisPool 和 Lettuce Connection Pool),但在设计和特性上有显著差异。下面我将详细对比它们的特点,帮助你更好地选择适合的库。 1. 同步 vs 异步 Jedis:是一个 同步 的 Redis 客…...
调试openai 星河大模型的记录:用tcpdump和ngrep抓包
在调试esp32开发板连星河大模型的时候,用requests连星河,怎么也调不通,想通过抓包,看看openai和自己写的到底有啥不一样。 结论:抓包抓到的太多,而且ssl 已经把一些信息都处理过了,看不到报文的…...
树莓派明明安装了opencv和numpy,却找不到
当然不止树莓派,配置python环境都可能存在这个问题 可能是因为安装的 numpy 或者 opencv 版本与 Python 的包路径不匹配。下面是问题的常见原因及解决方法:【方法一和二优先考虑】 原因分析 多版本 Python 环境冲突: 树莓派上可能有多个版本…...
【C++boost::asio网络编程】有关异步读写api的笔记
异步读写api 异步写操作async_write_someasync_send 异步读操作async_read_someasync_receive 定义一个Session类,主要是为了服务端专门为客户端服务创建的管理类 class Session { public:Session(std::shared_ptr<asio::ip::tcp::socket> socket);void Conn…...
github仓库自动同步到gitee
Github Actions是Github推出的自动化CI/CD的功能,我们将使用Github Actions让Github仓库同步到Gitee 同步的原理是利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中,所以我们需要以下几个步骤 生成 SSH 公私钥添加公钥添加私钥配…...
详解LinkedList中的底层实现
1.LinkedList的构造器 无参构造器 /*** Constructs an empty list.*/ public LinkedList() { } 构造Collection: 只要是 Collection 下的实现类都可以被 LinkedList 构造 // ? extends E: 只要是E的子类及E类型的类都可以使用 public LinkedList(Collection<? extends …...
HTML5动漫主题网站 天空之城 10页 html+css+设计报告成品项目模版
📂文章目录 一、📔网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站演示 五、⚙️网站代码 🧱HTML结构代码 💒CSS样式代码 六、🔧完整源码下载 七、📣更多 一、&#…...
【VSCode】如何修改左侧资源管理器字体大小
方法一 左下角的“设置”—> 选择“窗口” —> 找到 Zoom Level,一般1、2效果就挺大的,可以设置小数0.5、负数-1等,具体设置说明见下图: 这个有一点不好的是,不仅仅资源管理器字体变化,整个VSCode界面会跟着变…...
使用 Visual Studio 开发 Windows 服务
Windows 服务是一种后台运行的应用程序,可以在没有用户界面的情况下执行任务。以下是从概念到具体实现的详细说明。 1. 什么是 Windows 服务 Windows 服务是运行在 Windows 操作系统上的应用程序,具有以下特点: 后台运行:无需用…...
类型转换与IO流:C++世界的变形与交互之道
文章目录 前言🎄一、类型转换🎈1.1 隐式类型转换🎈1.2 显式类型转换🎁1. C 风格强制类型转换🎁2. C 类型转换操作符 🎈1.3 C 类型转换操作符详解🎁1. static_cast🎁2. dynamic_cast&…...
go的web框架介绍
Go 语言有许多优秀的 Web 框架,适用于不同类型的 Web 应用开发,涵盖从简单的 API 开发到复杂的微服务架构。以下是一些常见的 Go Web 框架: 1. Gin 简介:Gin 是一个高性能的 Go Web 框架,设计目标是让开发者能够以极…...
WPF+MVVM案例实战与特效(三十一)- 封装一个加载动画的自定义控件
文章目录 1、案例效果2、案例实现1、资源与文件创建2、自定义控件封装3、自定义控件使用4、总结1、案例效果 2、案例实现 在开发WPF应用程序时,我们常常需要一个灵活的加载动画控件,该控件可以根据窗口的大小自动调整其内部元素(如图片、边框和文本)的尺寸,并且能够通过简…...
cocos creator 3.8 抖音、字节跳动录制器 12
property(Node) luzhishijianDisplay: Node null!;//录制时间显示 property(Node) luzhikaishiBut: Node null!;//录制开始 property(Node) luzhijieshuBut: Node null!;//录制结束 luzhikaishiType: boolean false;//是否开始录制开始计时 gameluzhiTime: number 0;onLoa…...
汽车控制软件下载移动管家手机控车一键启动app
移动管家手机控制汽车系统是一款实现车辆远程智能控制的应用程序。通过下载并安装特定的APP,用户可以轻松实现以下功能:远程启动与熄火:无论身处何地,只要有网络,即可远程启动或熄火车辆,提前预冷或预…...
自由学习记录(28)
C# 中的流(Stream) 流(Stream)是用于读取和写入数据的抽象基类。 流表示从数据源读取或向数据源写入数据的矢量过程。 C# 中的流类是从 System.IO.Stream 基类派生的,提供了多种具体实现,每种实现都针对…...
HarmonyOS开发:关于签名信息配置详解
目录 前言 签名信息的重要性 签名的方式 自动化签名 1、连接真机 2、选择 手动签名 (一)生成密钥和证书请求文件 (二)申请调试证书 (三)注册调试设备 (四)申请调试Profil…...
react 组件双向绑定
1. 使用 state 实现双向绑定 对于双向绑定,需要同时处理表单元素的value属性(通过state来设置)和onChange事件(用于更新state)。 import { useState } from "react";const MyComponent () > {const [i…...
k8s api对象,CRD
在Kubernetes项目中,一个API对象在Etcd里的完整资源路径,是由:Group(API组)、Version(API版本)和Resource(API资源类型)三个部分组成 apiVersion: batch/v2alpha1 kind:…...
详解MyBatis之篇一
目录 MyBatis 定义 使用MyBatis操作数据库 创建项目 配置 演示 UserInfo.java UserInfoMapper UserInfoMapperTest 数据准备 自动生成测试类 运行结果 MyBatis 定义 MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避…...
uniapp连接mqtt频繁断开原因和解决方法
mqtt参考文档:MQTT.js 入门教程 | EMQ、MQTT.js 入门教程 - EMQX - 博客园 uniapp引用MQTT频繁断开的问题可能由于以下几个原因导致: 网络不稳定:频繁断开可能是由于网络不稳定导致的,可以尝试优化网络连接。 心跳机制问题&…...
网络安全内容整理二
网络嗅探技术 网络监听 网络监听,也称网络嗅探(Network Sniffing):在他方未察觉的情况下捕获其通信报文、通信内容的技术 网卡的工作模式: 1.广播模式(Broadcast Mode):网卡能够接收网络中的广播信息 2.组播模式(Multicast Mo…...
IDE解说
IDE(Integrated Development Environment,集成开发环境) 是一种集成了多种开发工具的软件应用程序,旨在简化软件开发过程。 IDE 通常包括代码编辑器、编译器或解释器、调试器、构建自动化工具和版本控制系统等组件。通过将这些工…...
安心护送转运平台小程序
安心护送转运平台小程序是一款基于FastAdminThinkPHPUniapp开发的非急救救护车租用转运平台小程序系统,可以根据运营者的业务提供类似短途接送救护服务,重症病人转运服务,长途跨省护送服务。...
mongodb文档字符串批量替换
【mongodb文档字符串批量替换脚本语句】 前言: 1、本方式对于数据量大的情况不适用,执行可能比较慢; 2、数据量大的情况,个人推荐代码层面解决,多线程替换更快: (1)写实体类的方式…...
模拟实现vector(非常详细)
模拟实现vector 1.基本概念2.vector()默认构造函数3.size()4.capacity()5.empty()6.reverse7.push_back()8.pop_back()9.operator[ ]10.resize()11.insert() 1.基本概念 上一节我们讲了vector的概念以及常用的接口,这一节我们讲一下它的实现,它的底层其实…...
证明直纹极小曲面是平面或者正螺旋面.
目录 证明直纹极小曲面是平面或者正螺旋面 证明直纹极小曲面是平面或者正螺旋面 证明:设极小直纹面 S S S的参数表示为 r ( u , v ) a ( u ) v c ( u ) . (u,v)\mathbf{a}(u)v\mathbf{c}(u). (u,v)a(u)vc(u).则 r u a ′ v c ′ , r v c , r u ∧ r v a ′ ∧…...
电子应用设计方案-34:智能镜子系统方案设计
智能镜子系统方案设计 一、引言 智能镜子作为一种新兴的智能设备,将传统镜子与现代科技相结合,为用户提供了丰富的信息展示和交互功能。它不仅可以作为普通镜子使用,还能够显示天气、新闻、日程安排等信息,甚至可以与智能家居设备…...
前端项目从开发到部署全流程介绍
一、项目初始化 创建项目目录 首先创建一个新的项目目录,例如my - front - end - project。使用命令mkdir my - front - end - project && cd my - front - end - project。 初始化项目 使用npm init或yarn init来初始化项目,这会生成一个packag…...
Vue3.0组件之间通信(defineProps 和 defineEmits 及 defineExpose)
前言: 一、父传子 defineProps二、子传父 defineEmits三、子组件暴露属性和方法给父组件 defineExpose四、依赖注入Provide / Inject 在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits ,它们具备完整的类型推…...
多种平台上安装部署调试Open5GS(四)
OpenWRT 源码安装 UERANSIM 安装依赖openwrt源码安装cmake其他依赖准备UERANSIM安装测试验证Open5GS 是一个功能完善的开源5G项目,具备5G、4G核心网功能,最新代码支持R17标准, 本系列文章介绍Open5GS在x86、ARM平台上的安装部署方法,并通过搭建UERANSIN、商用5G基站和终端两…...