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

【C++】map 和 set

文章目录

  • 一、关联式容器与键值对
    • 1、关联式容器
    • 2、键值对 pair
    • 3、树形结构的关联式容器
  • 二、set
    • 1、set 的介绍
    • 2、set 的使用
  • 三、multiset
  • 四、map
    • 1、map 的介绍
    • 2、map 的使用
  • 五、multimap

一、关联式容器与键值对

1、关联式容器

在C++初阶的时候,我们已经接触了 STL 中的部分容器并进行了模拟实现,比如 vector、list、stack、queue 等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身;

同样,关联式容器也是用来存储数据的,但与序列式容器不同的是,关联式容器里面存储的是 <key, value> 结构的键值对,因此在数据检索时比序列式容器效率更高

2、键值对 pair

键值对是用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量 – key 和 value;其中 key 代表键值,value 代表与 key 对应的信息。

我们在上一节学习二叉搜索树的时候提到的 KV 模型 (key-value 模型) 中的 KV 其实就是键值对;我们可以用上一节中提到的英汉互译的例子来理解 key-value 键值对 – 现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。

STL 中键值对的定义如下:(SGI 版本)

template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;   //keyT2 second;  //valuepair() : first(T1()), second(T2())  //默认构造{}pair(const T1& a, const T2& b) : first(a), second(b){}
};

可以看到,C++ 中的键值对是通过 pair 类来表示的,pair 类中的 first 就是键值 key,second 就是 key 对应的信息 value;那么以后我们在设计 KV 模型的容器时只需要在容器/容器的每一个节点中定义一个 pair 对象即可;

这里有的同学可能会有疑问,为什么不直接在容器中定义 key 和 value 变量,而是将 key、value 合并到 pair 中整体作为一个类型来使用呢?这是因为 C++ 一次只能返回一个值,如果我们将 key 和 value 单独定义在容器中,那么我们就无法同时返回 key 和 value;而如果我们将 key、value 定义到另一个类中,那我们就可以直接返回 pair,然后再到 pair 中分别去取 first 和 second 即可。

make_pair 函数

由于 pair 是类模板,所以我们通常是以 显式实例化 + 匿名对象 的方式来进行使用,但是由于显式实例化比较麻烦,所以 C++ 还提供了 make_pair 函数,其定义如下:

template <class T1, class T2>
pair<T1, T2> make_pair(T1 x, T2 y)
{return (pair<T1, T2>(x, y));
}

如上,make_pair 返回的是一个 pair 的匿名对象,匿名对象会自动调用 pair 的默认构造完成初始化;但由于 make_pair 是一个函数模板,所以模板参数的类型可以根据实参来自动推导完成隐式实例化,这样我们就不用每次都显式指明参数类型了。

注:由于 make_pair 使用起来比 pair 方便很多,所以我们一般都是直接使用 make_pair,而不使用 pair

3、树形结构的关联式容器

根据应用场景的不同,STL 总共实现了两种不同结构的关联式容器 – 树型结构与哈希结构;树型结构的关联式容器主要有四种 – map、set、multimap、multiset,这四种容器的共同点是使用平衡二叉搜索树作为其底层结构,容器中的元素是一个有序的序列;本文将介绍这四个容器的使用。


二、set

1、set 的介绍

set 是按照一定次序存储元素的容器,其底层是一棵平衡二叉搜索树,由于二叉搜索树的每个节点的值满足左孩子 < 根 < 右孩子,并且二叉搜索树中没有重复的节点,所以 set 可以用来排序、去重和查找,同时由于这是一棵平衡树,所以 set 查找的时间复杂度为 O(logN),效率非常高

同时,set 是一种 K模型 的容器,也就是说,set 中只有键值 key,而没有对应的 value,并且每个 key 都是唯一的;set 中的元素也不允许修改,因为这可能会破坏搜索树的结构,但是 set 允许插入和删除。image-20230323180144330

总结:

  1. set 是K模型的容器,所以 set 中插入元素时,只需要插入 key 即可,不需要构造键值对;
  2. set中的元素不可以重复,因此可以使用set进行去重;
  3. 由于 set 底层是搜索树,所以使用 set 的迭代器遍历 set 中的元素,可以得到有序序列,即 set 可以用来排序;
  4. set 默认使用的仿函数为 less,所以 set 中的元素默认按照小于来比较;
  5. 由于 set 底层是平衡树搜索树,所以 set 中查找某个元素,时间复杂度为 O(logN);
  6. set 中的元素不允许修改,因为这可能破坏搜索树的结构;
  7. set 中的底层使用平衡二叉搜索树 (红黑树) 来实现。

注:可能有的同学对 O(logN) 的时间复杂度没有什么具体的概念,那么我们可以列举一组数据大家就很清楚了:set 从1000个数据找查找某个数据最多找10次,从100万个数据中找某一个数据最多找20次,从10亿个数据中找某一个数据最多找30次;换一种说法,如果以身份证号作为 key 值存入 set 中 (假设内存足够),那么我们从地球所有人类中查找某一个身份证号对应的人时最多只用找 31 次;相信现在大家对 O(logN) 是什么量级的存在已经有了很清楚的认识了。

2、set 的使用

构造

和传统容器一样,set 也支持单个元素构造、迭代器区间构造以及拷贝构造:image-20230323180553971

迭代器

迭代器也一样,包括正向迭代器和反向迭代器,正向和反向又分为 const 和 非const:image-20230323181709675

修改

set 有如下修改操作:image-20230323182250500

其中 swap 就是交换两棵树的根,clear 就是释放树中的所有节点,emplace 和 emplace_hint 我们放在 C++11 章节中学习,大家现在不用管它;最重要的修改操作是 insert 和 erase;

insert 支持插入一个值、在某个迭代器位置插入值、插入一段迭代器区间,我们学会第一个即可,插入的过程就是二叉搜索树的插入过程;需要注意的是 insert 的返回值是 pair 类型,pair 中第一个元素代表插入的迭代器位置,第二个元素代表是否插入成功 (插入重复节点会返回 false):image-20230323182503760

erase 也有三种,常用的是第一种和第二种,删除指定键值的数据和删除指定迭代器位置的数据:image-20230323183111734

操作

set 还有一些其他操作相关的函数:image-20230323183411290

其中比较重要的只有 find,由于 set 中不允许出现相同的 key,因此在 set 中 count 函数的返回值只有1/0,可以说没有什么价值,set 中定义 count 主要是因为 count 在 multiset 中有作用,这里是为了保持一致;lower_bound 和 upper_bound 是得到一个左闭右开的迭代器区间,然后我们可以对这段区间进行某些操作,但实际中其实没什么人用;

find 的作用是在搜索树中查找 key 对应的节点,然后返回节点位置的迭代器,如果找不到,find 会返回 end():image-20230323184212751

set 使用范例

void set_test() {// 用数组array中的元素构造setint array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };set<int> s(array, array + sizeof(array) / sizeof(array[0]));cout << s.size() << endl;// 正向打印set中的元素,从打印结果中可以看出:set可去重for (const auto& e : s)cout << e << " ";cout << endl;// 使用迭代器逆向打印set中的元素for (auto it = s.rbegin(); it != s.rend(); ++it)cout << *it << " ";cout << endl;// 查找+删除set<int>::iterator pos = s.find(9);if (pos != s.end())s.erase(pos);//输出key为9的节点的个数cout << s.count(9) << endl;  
}

image-20230323184825402

如果大家对 set 的使用还有不清楚的地方,建议查阅 set 文档:set - C++ Reference (cplusplus.com)


三、multiset

multiset 的介绍

multiset 也是 K模型 的容器,它和 set 唯一的区别在于 multiset 中允许存在重复的 key 值节点,所以 multiset 可以用来排序和查找,但是不能用来去重。

multiset 的使用

multiset 的使用其实和 set 也几乎一样,唯一需要注意的是 find 和 count 函数 – 由于 multiset 中允许存在重复 key 值的节点,所以 multiset 中 count 函数就有作用了,我们可以通过 count 函数来统计同一 key 中在 multiset 中的数量:image-20230323194646245

multiset 中 find 函数的使用也和 set 有所区别 – 由于 set 中没有重复的节点,所以 find 时要么返回该节点位置的迭代器,要么返回 end();而 multiset 中可能有重复的节点,所以 find 时返回的是同一 key 值中的哪一个节点呢?实际上 find 返回的是中序遍历过程中第一个匹配的节点位置的迭代器image-20230323195419090

multiset 使用范例

void multiset_test() {// 用数组array中的元素构造multisetint array[] = { 1, 3, 5, 7, 3, 2, 4, 6, 8, 0, 1, 3, 5, 7, 3, 2, 4, 6, 8, 3 };multiset<int> s(array, array + sizeof(array) / sizeof(array[0]));cout << s.size() << endl;// 正向打印multiset中的元素,从打印结果中可以看出:multiset允许重复元素的出现for (const auto& e : s)cout << e << " ";cout << endl;//如果查找的key在multiset中有多个,则返回中序遍历中遇到的第一个节点的迭代器multiset<int>::iterator pos = s.find(3);while (pos != s.end()) {cout << *pos << " ";++pos;}cout << endl;// 查找+删除//输出key为3的节点的个数cout << s.count(3) << endl;pos = s.find(3);if (pos != s.end())s.erase(pos);cout << s.count(3) << endl;
}

image-20230323200250179

如果大家对 multiset 的使用还有不清楚的地方,建议查阅 multiset 文档:multiset - C++ Reference (cplusplus.com)


四、map

1、map 的介绍

map 和 set 一样都是按照一定次序存储元素的容器,其底层也是一棵平衡二叉搜索树;和 set 不同的是,map 是 KV模型 的容器,在map 中,键值 key 通常用于排序和惟一地标识元素,而值 value中 用于存储与此键值 key 关联的内容,键值 key 和值value的类型可以不同;在 map 内部,key-value 通过成员类型 pair 绑定在一起,也就是我们文章开始提到的键值对

需要注意的是:map 中的元素是按照键值 key 进行比较排序的,而与 key 对应的 value 无关,同时,map 中也不允许有重复 key 值的节点;map 也可用于排序、查找和去重,且 map 查找的时间复杂度也为 O(logN)。image-20230323201008877

特别注意:map 允许修改节点中 key 对应的 value 的值,但是不允许修改 key,因为这样可能会破坏搜索树的结构

2、map 的使用

构造

image-20230323201622323

迭代器

image-20230323201653112

修改

image-20230323202623919

修改中的重点的仍然是 insert 和 erase,swap 为交换两棵树的根,clear 为释放树中的每一个节点;

和 set 一样,map 的 insert 也支持插入一个值、在某个迭代器位置插入值、插入一段迭代器区间,我们还是学会第一个即可,插入的过程就是二叉搜索树的插入过程;需要注意的是 insert 的返回值是 pair 类型,pair 中第一个元素代表插入的迭代器位置,第二个元素代表是否插入成功 (插入重复节点会返回 false)::image-20230323202826103

erase 一样也有三种,常用的是第一种和第二种,删除指定键值的数据和删除指定迭代器位置的数据:image-20230323203132825

元素访问

需要重点注意的是,map 重载了 [] 运算符,其函数原型如下:

//mapped_type: pair中第二个参数,即first
//key_type: pair中第一个参数,即second
mapped_type& operator[] (const key_type& k);

函数定义如下:

mapped_type& operator[] (const key_type& k) 
{(*((this->insert(make_pair(k, mapped_type()))).first)).second;
}

可以看到,map 中 operator[] 函数的实现看起来非常复杂,我们可以将它拆解一下:

V& operator[] (const K& k)
{pair<iterator, bool> ret = insert(make_pair(k, V()));//return *(ret.first)->second;return ret.first->second;
}

可以看到,operator[] 函数会先向 map 中插入 k,这里插入的结果有两种 – 如果 map 中已经有与该值相等的节点,则插入失败,返回的 pair 中存放着该节点位置的迭代器和false;如果 map 中没有与该值相等的节点,则会向 map 中插 key 值等于 k 的节点,该节点对应的 value 值为 V 默认构造的缺省值;

然后,operator[] 会取出 pair 中的迭代器 (ret.first),然后对迭代器进行解引用得到一个 pair<k, v> 对象,最后再返回排 pair 对象中的 second 的引用,即 key 对应的 value 的引用;所以我们可以在函数外部直接修改 key 对应的 value 的值image-20230323204954760

所以,map 中的 operator[] 是集插入、查找、修改为一体的一个函数;示例如下:image-20230323205942366

注意:

  1. 这里修改的是 key 对应的 value,而并没有修改 key,所以并没有破坏搜索树的结构;
  2. 我们上面拆解 operator[] 函数时之所以能将 *(ret.first)->second 改写为 ret.first->second 是因为编译器为了可读性省略了一个 -> 操作符,实际上应该是 ret.first->->second;关于这里的细节我在 list 模拟实现 中说过,有兴趣的可以去看看。

操作

和 set 一样,map 中有 count 函数是因为 multimap 需要count 函数,这里是为了保持一致性:image-20230323210452737

map 使用范例

void map_test() {map<string, string> m;//向map中插入元素的方式:用pair直接来构造键值对m.insert(pair<string, string>("peach", "桃子"));//为了方便,我们建议直接用make_pair函数来构造键值对m.insert(make_pair("banan", "香蕉"));// 借用operator[]向map中插入元素,operator[]的原理如下://--------------------------------------------------------------------------------------//// 用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中// 如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器// 如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器// operator[]函数最后将insert返回值键值对中的value返回// 注意:通过[]插入的键值对的value使用默认构造完成初始化,我们需要通过修改[]的返回值来对其重新赋值//---------------------------------------------------------------------------------------//// 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引用结果,m["apple"] = "苹果";// 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列for (auto& e : m)cout << e.first << ":" << e.second << endl;cout << endl;// map中的键值对key一定是唯一的,如果key存在将插入失败auto ret = m.insert(make_pair("peach", "桃色"));if (ret.second)cout << "<peach, 桃色>不在map中, 已经插入" << endl;elsecout << "键值为 peach 的元素已经存在:" << ret.first->first << "--->" << ret.first->second << " 插入失败" << endl;// 删除key为"apple"的元素m.erase("apple");if (1 == m.count("apple"))cout << "apple还在" << endl;elsecout << "apple被吃了" << endl;
}

image-20230323211450381

如果大家对 map 的使用还有不清楚的地方,建议查阅 map 使用文档:map - C++ Reference (cplusplus.com)


五、multimap

和 set 与 multiset 的关系一样,multimap 存在的意义是允许 map 中存在 key 值相同的节点,multimap 与map 的区别和 multiset 与 set 的区别一样 – find 返回中序遍历中遇到的第一个节点的迭代器,count 返回和 key 值相等的节点的个数:image-20230323211919225

image-20230323211950647

需要注意的是,multimap 中并没有重载 [] 运算符,因为 multimap 中的元素是可以重复的,如果使用 [] 运算符,会导致多个元素的 key 值相同,无法确定具体访问哪一个元素。

如果大家对 multimap的使用还有不清楚的地方,建议查阅 multimap文档:multimap - C++ Reference (cplusplus.com)


相关文章:

【C++】map 和 set

文章目录一、关联式容器与键值对1、关联式容器2、键值对 pair3、树形结构的关联式容器二、set1、set 的介绍2、set 的使用三、multiset四、map1、map 的介绍2、map 的使用五、multimap一、关联式容器与键值对 1、关联式容器 在C初阶的时候&#xff0c;我们已经接触了 STL 中的…...

基于SpringBoot的酒店管理系统

系统环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/i…...

JAVA框架知识整理

框架知识整理 SpringBoot、SpringMVC、Spring的区别和他们的作用&#xff1f; SpringBoot是一个微服务框架&#xff0c;其简化了Spring应用的创建、运行、测试、部署。使开发人员无需过多的关注XML配置。里面整合了许多框架例如SpringMVC、Spring Security和Spring Data JPA。…...

运算放大器:电压比较器

目录一、单限电压比较器二、滞回电压比较器三、窗口电压比较器最近在学习电机控制&#xff0c;遇到了与运算放大电路相关的知识&#xff0c;然而太久没有接触模拟电路&#xff0c;对该知识已经淡忘了&#xff0c;及时温故而知新&#xff0c;做好笔记&#xff0c;若有错误、不足…...

Linux的基础知识

根目录和家目录根目录&#xff1a;是Linux中最底层的目录&#xff0c;用"/"表示家目录&#xff1a;当前用户所在的路径&#xff0c;用“~”表示&#xff0c;root用户的家目录和普通用户的家目录不一样&#xff0c;普通用户的家目录在/home路径下&#xff0c;每一个用…...

【JavaEE】 IntelliJ IDEA 2022.2最新版Tomcat导入依赖详细教程全解及创建第一个Servlet程序

目录 一、软件资源 二、放置settings.xml文件 三、创建项目 四、引入依赖 ​五、创建目录 六、编写代码 写在前面&#xff1a;☞What is Servlet? Servlet其实是一种实现动态页面的技术。是一组由Tomcat提供给程序员的API&#xff08;应用程序编程接口&#xff09;…...

常见的卷积神经网络结构——分类、检测和分割

本文持续更新~~ 本文整理了近些年来常见的卷积神经网络结构&#xff0c;涵盖了计算机视觉领域的几大基本任务&#xff1a;分类任务、检测任务和分割任务。对于较复杂的网络&#xff0c;本文只会记录其中的核心模块以及重要的网络设计思想&#xff0c;并不会记录完整的网络结构。…...

20230323英语学习

Why Can You “Hear the Ocean” in Seashells? 为啥能在贝壳里“听见海的声音”&#xff1f; We’re told a number of stories as kids. One of the more harmless of these little lies is the one about seashells.You know the one: hold up a seashell to your ear, an…...

【粉丝投稿】上海某大厂的面试题,岗位是测开(25K*16)

简单介绍一句&#xff0c;大专出身&#xff0c;三年经验。跳了四次槽&#xff0c;面试了无数次&#xff0c;现在把自己的面试经验整理出来分享给大家&#xff0c;堪称必杀技&#xff01; 1&#xff0c;一切从实际出发&#xff0c;对实际工作进行适当修饰 2&#xff0c;不会的简…...

shell简单使用介绍

脚本的基本元素声明&#xff0c;在解释并执行当前脚本文件中的语句之前&#xff0c;需要声明使用的命令解释器#一般写的解释器为 #!/bin/bash这里的#不再是注释了&#xff0c;而是必要的声明命令&#xff0c;也就是需要执行的语句注释&#xff0c;对代码进行解释说明分为单行注…...

RK3568平台开发系列讲解(调试篇)内核函数调用堆栈打印方法汇总

🚀返回专栏总目录 文章目录 一、dump_stack 函数二、WARN_ON(condition)函数三、BUG_ON (condition)函数四、panic (fmt...)函数沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对驱动调试方法进行汇总学习。 一、dump_stack 函数 dump_stack 作用:打印内核调…...

一次内存泄露排查

前因&#xff1a; 因为测试 长时间压测导致 接口反应越来越慢&#xff0c;甚至 导致服务器 崩溃 排查过程 1、top 查看是 哪个进程 占用 内存过高 2、根据 进程 id 去查找 具体是哪个 程序的问题 ps -ef| grep 41356 可以看到 具体的 容器位置 排查该进程 对象存活 状态…...

「Mac安装ps」Adobo Photoshop 2023 下载安装详情教程,支持 AI 插件的 24 版 Photoshop

前言 Adobo Photoshop 2023 已推出&#xff0c;由于目前AI人工智能技术火爆&#xff0c;而很多的 AI 插件最低也需要24版的 photoshop &#xff0c;所以这里我遍搜集并整理了此新版本的 photoshop 安装使用教程&#xff0c;后续也将提供 AI 插件的下载安装教程 安装文件下载 …...

Redis单线程还是多线程?IO多路复用原理

目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程&#xff1f;三、Redis6.0引入多线程四、Redis主线程和IO线程是如何完成请求的&#xff1f;1、服务端和客户端建立socket连接2、IO线程读取并解析请求3、主线程执行请求命令4、IO线程会写回socket和主线程清…...

小菜鸟Python历险记:(第五集)

今天写的文章是记录我从零开始学习Python的全过程。在Python中对方法进行备注的时候&#xff0c;往往都是写在方法中的第一行所在位置。在书写注释以后&#xff0c;在调用方法的时候&#xff0c;鼠标点击方法会有一个浮动的提示显示备注内容。具体如下图所示&#xff1a;注释的…...

【思维模型】五分钟了解<复利思维>,为何学习复利思维?什么是复利思维?如何应用复利思维?

【思维模型】五分钟了解&#xff1c;复利思维&#xff1e;&#xff0c;为何学习复利思维&#xff1f;什么是复利思维&#xff1f;如何应用复利思维&#xff1f;1. 为何学习复利思维&#xff1f;2. 什么是复利思维&#xff1f;3. 如何应用复利思维&#xff1f;4. 小结参考&#…...

Vue.js语法详解:从入门到精通

Vue.js是一个流行的JavaScript框架&#xff0c;用于构建用户界面。它的核心特性包括数据双向绑定、组件化架构、虚拟DOM和响应式系统等。在本文中&#xff0c;我们将深入探讨Vue.js的语法&#xff0c;帮助读者更好地理解和应用Vue.js。1.模板语法Vue.js的模板语法采用了类似HTM…...

程序员的代码行数越少越好?

有些人可能会认为&#xff0c;应用程序中的代码行越少&#xff0c;就越容易阅读。这句话只有部分正确&#xff0c;我认为代码可读性的度量标准包括&#xff1a;代码应具备一致性代码应具备自我描述性代码应具备良好的文档代码应使用稳定的现代功能代码不应过于复杂代码的性能不…...

【每日一题Day156】LC1032字符流 | 字典树

字符流【LC1032】 设计一个算法&#xff1a;接收一个字符流&#xff0c;并检查这些字符的后缀是否是字符串数组 words 中的一个字符串。 例如&#xff0c;words ["abc", "xyz"] 且字符流中逐个依次加入 4 个字符 a、x、y 和 z &#xff0c;你所设计的算法…...

V2G模式下含分布式能源网优化运行研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff1a;&#x1f381;&#x1f381;&#x1f381; 目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &am…...

手写一个简单的RPC框架

学习RPC框架&#xff0c;由繁化简&#xff0c;了解其本质原理 文章目录项目简介什么是RPC&#xff1f;项目模块项目代码common模块client模块server模块framework模块测试项目简介 什么是RPC&#xff1f; RPC&#xff08;Remote Procedure Call&#xff09;即远程过程调用&am…...

【剑指offer】旋转数组的最小数字

&#x1f451;专栏内容&#xff1a;剑指offer⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录一、题目描述1、题目2、示例示例1示例2二、题目分析1、暴力法2、二分法三、代码汇总1、暴力法2、二分法一、题目描述 1、题…...

【Dorker】Portainer轻量级可视化工具

文章目录Portainer简介登录Portainer第一次登录需创建admin&#xff0c;访问地址&#xff1a;xxx.xxx.xxx.xxx:9000选择local选项卡后本地docker详细信息展示安装nginx私有镜像仓库管理Portainer简介 Portainer是Docker的图形化管理工具&#xff0c;提供状态显示面板、应用模板…...

基于 vue.js 进行组件封装的方案

摘要&#xff1a;本文将介绍如何基于 vue.js 进行组件封装的方案。我们将从分析组件封装的优势开始&#xff0c;然后依次介绍 vue.js 的基本概念&#xff0c;以及如何创建、封装和使用自定义组件。最后&#xff0c;我们将通过一个实际的示例&#xff0c;演示如何实现一个基于 v…...

【Unityc#专题篇】之c#基础篇

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…...

Python(白银时代)——模块、包、异常

异常 概念 程序运行时&#xff0c;如果Python 解释器遇到了错误&#xff0c;会停止程序运行&#xff0c;并且提示错误信息&#xff0c;这就是异常 程序停止执行并提示错误信息的动作&#xff0c;称为 抛出异常 异常捕获 try: 里面的代码&#xff0c;不确定是否能够正常执行. …...

小程序和Vue写法的区别

小程序和Vue写法的区别主要有以下几点&#xff1a; 语法不同&#xff1a;小程序使用的是WXML、WXSS和JS&#xff0c;而Vue使用的是HTML、CSS和JSX。 数据绑定方式不同&#xff1a;小程序使用的是双向数据绑定&#xff0c;而Vue使用的是单向数据流。 1&#xff09;在小程序中需…...

如何实现分布式锁

一、锁的作用 锁是为了解决多线程情况下&#xff0c;对于共享资源的访问安全问题。 但是当系统是分布式的时候&#xff0c;本地锁已经没法锁住所需要的资源&#xff0c;因为本地获取了锁&#xff0c;其他系统无法得知本地锁的情况。 分布式锁&#xff0c;是独立于系统的第一方…...

使用VS2019连接Microsoft SQL Server Compact 4.0数据库

简介 SQL Server Compact Edition是微软推出的一个适用于嵌入到移动应用的精简数据库产品&#xff0c;Windows Mobile开发人员能够使用SQL Server CE开发出将数据管理能力延展到Window Mobile移动设备上的应用程序。虽然SQL Server CE占用的磁盘空间只有3到5兆左右&#xff0c…...

Vue2 和 Vue3 的对比

Vue2 vs Vue3 Vue 是一款流行的 JavaScript 框架&#xff0c;用于构建交互式 Web 界面。Vue2 和 Vue3 是 Vue.js 的两个版本。Vue3 是 Vue.js 的最新版本&#xff0c;于 2020 年 9 月正式发布。Vue3 有许多改进和新功能&#xff0c;下面我们将对 Vue2 和 Vue3 进行比较。 性能…...

北京网站备案公司/郑州seo技术培训班

display&#xff1a;none指的是元素完全不陈列出来&#xff0c;不占据空间&#xff0c;涉及到了DOM结构&#xff0c;故产生reflow与repaint visibility&#xff1a;hidden指的是元素不可见但存在&#xff0c;保留空间&#xff0c;不影响结构&#xff0c;故只产生repaint 隐藏元…...

wordpress邮件发验证码/百度视频下载

编写了一个简单的示例应用程序 &#xff0c;演示如何使用TCP v4 LAN传输。 它会根据您在帖子中添加的设置设置参与者。 请注意&#xff0c;发布者和订阅者应用程序的参与者共享与我在下面的代码片段中设置的相同的QoS设置。 唯一的区别是发布服务器和订阅服务器应用程序中的…...

保定做网站的公司/免费发布信息的平台

作为一名产品经理&#xff0c;最奢侈的愿望是什么&#xff1f;“有一个自己能控制的团队去实现心目中的产品”&#xff0c;应该不仅仅是我有这个想法吧。按照比较流行的说法&#xff0c;产品经理是只负责产品规划与管理、不直接负责团队管理的“经理”&#xff0c;但却身负推动…...

东莞清洁服务网站建设/关键词优化的作用

首先&#xff0c;关注破千了&#xff0c;感谢大家的支持。D2-Net A Trainable CNN for Joint Description and Detection of Local Featureshttps://arxiv.org/pdf/1905.03561.pdf​arxiv.org一、论文出发点传统的关键点检测&#xff0c;例如&#xff33;&#xff29;&#xf…...

ssm做的直播网站/北京网络营销推广培训哪家好

1080P实战利器搭建最近《使命召唤&#xff1a;战区》热度还在持续攀升&#xff0c;前段时间硬核写过一个关于这款游戏6000元的配置推荐&#xff0c;才没过一个星期&#xff0c;官方Twitter再次宣布玩家人数翻倍突破3000万&#xff0c;想起评论区有玩家反映最近装机成本太高&…...

广东省住房和城乡建设部网站/网上如何推广自己的产品

涉及到的知识点1、设计一个完整程序的流程 2、HTML部分表单标签的使用 3、PHP里的页面相互调用 4、PHP接收参数的几种方式首先做的就是html表单的显示部分&#xff0c;创建一个文件&#xff08;list.php&#xff09;内容&#xff08;‘//’后边是注释&#xff09;&#xff1a;&…...