C++:关联容器及综合运用:

关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字保存访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。关联容器因此相比与顺序容器支持高效的关键字查找和访问

其底层数据结构顺序关联容器 ->红黑树,插入和查找的时间复杂度为 O(log n)

无序关联容器 ->哈希表,插入查找的时间复杂度为O(1)

1. 关联容器介绍:

1.1. pair 数对:

pair是一个模板类,使用时需要引用<utility>文件

#include <utility>//通用工具

pair可将两个value处理为一个元素。C++标准库内多处用到了这个结构。尤其容器 map、unordered_map和unordered_multimap就是使用pair来管理其内部元素(key_value),任何函数如果需返回两个 value,也需要用到pair,例如minmax()最大最小值

1.1.1. 基础操作:

1.2. 有序关联容器:

1.2.1. set 和multiset:

使用set或multiset,必须先包含头文件<set>:

#include <set>

上述两个类型都被定义为命名空间std内的class template:

namespace std {template <typename T,typename Compare = less<T>,typename Allocator = allocator<T> >class set;template <typename T,typename Compare = less<T>,typename Allocator = allocator<T> >class multiset;
}

其中T是能进行排序的数据类型。第二个参数是进行排序的规则,默认为升序(小于,<)。第三个是内存分配器,不用管。

set 和multiset通常用平衡二叉树(balanced binary tree,确切说是红黑树)实现。这样在插入数据时能自动排序,使得查找元素时有良好性能。其查找函数具有对数O(logn)时间复杂度。

但是,自动排序也造成set和multiset的一个重要限制:你不能直接改变元素值,因为这样会打乱原本正确的顺序。

1.2.1.1. 基础操作:

set和multiset支持双向迭代器,不支持随机迭代器

可以往前和往后,但不能+1,-1(这是随机迭代器)等。

1.2.1.2. 常用函数:

1.2.1.3. set应用场景
去重操作

当需要从一个数据集合中去除重复元素时,set是一个很好的选择。由于其不允许存储重复的元素,因此可以很容易地实现去重功能。这在处理原始数据或进行数据分析时特别有用。

自动排序

如果需要对元素保持持续的排序状态,如维持一个按字母顺序排列的单词列表、存储并维护一个按年龄升序或降序排列的人口数据库等,std::set 可以实现这一功能。每次插入新元素,容器都会自动调整元素的顺序。

  • 当然如果仅仅是排序,可以使用sort函数进行排序.
  • sort排序是在排序瞬间的,如果又插入新的数据可能不再有序
  • set的有序是持续的,不管插入还是删除数据它始终有序
快速查找

由于set内部采用了高效的平衡查找二叉树(如红黑树),因此它提供快速的查找性能。包括检查元素是否已存在(.count() 或 .find())、查找特定值的下一个/前一个元素(迭代器操作)。这对于实现诸如查找词汇表中的下一个更大词、或者在游戏中查找排名高于当前玩家的下一个玩家等场景很有用。

1.2.2. map和multimap:

map和 multimap映射 将 key - value数对(也称键值对)当作元素进行管理,它们可根据 key 的排序准则自动为元素排序。multimap 允许key重复,map 不允许key重复,对于value不考虑 。

使用map和multimap必须引用头文件map

#include <map>
using namespace std;

map和multimap 会根据元素的 key 自动对元素排序。这么一来,根据已知的 key 查找某个元素时就能够有很好的效率O(logn),而根据已知 value 查找元素时,效率就很糟糕 O(n)

1.2.2.1. 常用迭代器:

map和multimap支持双向迭代器,不支持随机迭代器,可以往前和往后,但不能+1,-1(这是随机迭代器)等。

1.2.2.2. 常用运算符:
  • [ ]是map中最重要和常用的运算符,它可以通过key访问元素。如果这个key存在则返回元素的引用,如果key不存在则添加新元素。但multimap不支持[ ]
  • 注意m[key]中的key是关键字,可以是任意类型,不是下标。map和multimap没有下标访问

1.2.2.3. 常用函数:

1.2.3. 有序关联容器特有函数:

lower_bound成员函数

返回第一个元素值 >= val的位置(迭代器)。

upper_bound成员函数

返回第一个元素值 > val的位置(迭代器)。

int main()
{set<int> s1{1, 2, 3, 4, 5};auto it1 = s1.lower_bound(2);if (it1 != s1.end())//找到>=2的迭代器cout << "在s1中找到>=2的元素" << * it1 << endl;set<int>::iterator it2 = s1.lower_bound(6);if (it2 == s1.end())//没有找到>=6的元素cout << "在s1中没有找到>=6的元素" << endl;it1 = s1.upper_bound(2);//找>2的迭代器if (it1 != s1.end())//找到>2的迭代器cout << "在s1中找到>2的元素" << *it1 << endl;multiset<int> s2{1, 1, 2, 3, 3, 4, 5, 5};auto it3 = s2.upper_bound(4); //找>4的迭代器if (it3 != s2.end())//找到>4的迭代器cout << "在s2中找到>4的元素" << *it3 << endl;auto p = s2.equal_range(3);//查找3的区间if ((p.first != s2.end()) && (p.second != s2.end())){cout<< "在s2中找3的区间是(第一个>=3 ~ 第一个>3):" << *p.first << "~" << *p.second;}return 0;
}

1.3. 无序关联容器:

无序(unordered)容器也称无序关联(unordered associative)容器。unordered 无序容器存放的元素是无序的。无序容器一个有4个,分别是unordered set ,unordered multiset, unordered map,unordered multimap。

使用unordered set 或者unordered multiset需要引用<unordered_set>头文件

#include <unordered_set>

使用unordered map或者unordered multimap需要引用<unordered_map>头文件。

#include <unordered_map>

这四个类型都是定义在std中的类模板。

namespace std{template <typename T,typename Hash = hash<T>,typename EqPred = equal_to<T>,typename Allocator = allocator<T> >class unordered_set;//unordered_set类template <typename T,typename Hash = hash<T>,typename EqPred = equal_to<T>,typename Allocator = allocator<T> >class unordered_multiset;//unordered_multiset类template <typename Key, typename T,typename Hash = hash<T>,typename EqPred = equal_to<T>,typename Allocator = allocator<pair<const Key,T>>>class unordered_map;//unordered_map类template <typename Key,typename T,typename Hash = hash<T>,typename EqPred = equal_to<T>,typename Allocator = allocator<pair<const Key,T>>>class unordered_multimap;//unordered_multimap类
}

其中T是value值的类型,Key是关键字类型。

如果没有指明hash 函数,就使用默认的hash<>,这个函数可以用于所有内置类型、指针、string及若干特殊类型。对于自定义的类型可能需要自定义hash 函数。

EqPred,用来判断两个元素是否相等。默认使用equal_to<>。它会以operator==比较两个元素。

这几个无序容器内部利用hash table(哈希表)为基础。

无序关联容器除了没有有序关联容器特有的比较函数,其他与有序关联容器的函数用法类似

2. 无序容器布局操作函数

无序容器内部利用hash table(哈希表)为基础

上图是unordered set/multiset的内部结构图,通过哈希函数将数据value映射到某个bucket(slot 桶)

上图是unordered map/multimap的内部结构图,通过哈希函数将数据key-value映射到某个bucket(slot 桶)中。

每一个bucket管理一个链表,这个链表包含的是通过哈希函数产生相同哈希值的元素。这个链表是单链表还是双向链表C++标准并没有规定。(vs2022是双向链表)。下面两行代码是vs2022 xhash 文件中的代码

//插入新节点,需要修改前驱指针和后继指针
_Insert_after->_Next  = _Newnode;
_Insert_before->_Prev = _Newnode;

通过hash管理在插入,删除和查找元素时都能达到平均常量(O(1))时间的复杂度。

int main()
{unordered_set<int>s1{1,2,4,2,4,2,4,2,6,6,7,8,9,5,11,22,33,44};auto hashfun = s1.hash_function();//获取当前的哈希函数,默认的hash函数cout << "hashfun(11) = " << hashfun(11) << endl;//内部在计算桶编号时对这个值又进行了计算cout << "val为2 的桶值编号 = " << s1.bucket(2)<<endl;cout << "val为2 的桶值编号 = " << s1.bucket(4) << endl;cout << "val为2 的桶值编号 = " << s1.bucket(6) << endl;cout << "val为2 的桶值编号 = " << s1.bucket(7) << endl;cout << "val为2 的桶值编号 = " << s1.bucket(8) << endl;cout << "val为2 的桶值编号 = " << s1.bucket(9) << endl;int n = s1.bucket_count();cout << " 桶的总数量为:" << n << endl;for (int i = 0; i < n; i++){cout << i << "号桶的数据个数为:" << s1.bucket_size(i) << endl;}cout << "桶的平均元素个数为(负载因子):" << s1.load_factor()<<endl;cout << "桶的最大元素个数为(负载因子):" << s1.max_load_factor() << endl;cout << "重新生成哈希表后的hash函数为s1.rehash(15):" << endl;s1.rehash(99);cout << "桶的平均元素个数为(负载因子):" << s1.load_factor() << endl;cout << "桶的最大元素个数为(负载因子):" << s1.max_load_factor() << endl;return 0;
}

3. 综合应用:

3.1. 1.测试有序容器和无序容器性能差别:

生成1,000,000个随机数,范围(0~100000000 ,1亿),分别插入到set和unordered_set中,统计插入的时间区别,统计查找的时间区别。

步骤:

  1. 产生1,000,000个随机数并保存到vector中(保证数据样本相同)。
  2. 把这1,000,000个数字从vector插入到set中并记录时间\插入到unordered_set中并记录时间。
  3. 在set中\在unordered_set查询0~1,000,000(不需要记录是否查询成功)并记录时间。

#include <iostream>
#include <random>
#include <set>
#include <unordered_set>
using namespace std;int main()
{vector<unsigned int>v;set<unsigned int>s1;unordered_set<unsigned int> s2;const int n = 1000000;//数据样本 1百万default_random_engine engine;//默认随机引擎 uniform_int_distribution<unsigned int> di(0, 100000000);//随机数范围0~1亿//给向量v插入数据for (int i = 0; i < n; ++i) //产生随机数,并存放到v中v.push_back(di(engine));//把数据插入到set集合中并记录时间 clock_t c1 = clock();for (auto x : v)s1.insert(x);clock_t c2 = clock();//结束插入数据//把数据插入到unordered_set集合中并记录时间 for (auto x : v)s2.insert(x);clock_t c3 = clock();cout << "插入1百万数据时间比较. set:" << c2 - c1;cout<< "毫秒,unordered_set:"<<c3-c2<<"毫秒"<< endl;//在set中查询0~1,000,000并统计时间c1 = clock();for (unsigned int i = 0; i < 1000000; i++)s1.find(i);//不处理查询结果c2 = clock();//在unordered_set中查询0~1,000,000并统计时间for (unsigned int i = 0; i < 1000000; i++)s2.find(i);//不处理查询结果c3 = clock();cout << "查询1百万数据时间比较. set:" << c2 - c1;cout << "毫秒,unordered_set:" << c3 - c2 << "毫秒" << endl;return 0;
}

关联容器(set,multiset,map,multimap)有序,插入的时间复杂度为O(logn),查询的时间复杂度为O(logn)

无序容器(unordered_set,unordered_multiset,unordered_map,unordered_multimap),内部利用哈希表,插入的时间复杂度平均为O(1),查询的时间复杂度平均为O(1)

如果对数据有序性没有要求,请优先使用无序容器。

3.2. 2.测试无序容器最大负载因子对性能的影响:

#include <iostream>
#include <random>
#include <unordered_set>
#include<vector>
using namespace std;//2.测试无序容器最大负载因子对性能的影响
int main()
{vector<unsigned int>v;unordered_set<unsigned int>s;//s1为默认负载因子unordered_set<unsigned int>s1;//可设置负载因子unordered_set<unsigned int>s2;//可设置负载因子unordered_set<unsigned int>s3;//可设置负载因子unordered_set<unsigned int>s4;//可设置负载因子unordered_set<unsigned int>s5;//可设置负载因子unordered_set<unsigned int>s6;//可设置负载因子unordered_set<unsigned int>s7;//可设置负载因子s1.max_load_factor(0.1f);//设置最大负载因子s2.max_load_factor(0.2f);//设置最大负载因子s3.max_load_factor(0.3f);//设置最大负载因子s4.max_load_factor(0.4f);//设置最大负载因子s5.max_load_factor(0.5f);//设置最大负载因子s6.max_load_factor(0.6f);//设置最大负载因子s7.max_load_factor(0.7f);//设置最大负载因子const int n = 1e6;//数据样本 1百万default_random_engine engine;//默认随机引擎uniform_int_distribution<unsigned int>rand;//随机数范围0~1亿//给向量v插入数据for (int i = 0; i < n; i++)v.push_back(rand(engine));//插入生成的随机数//把数据插入到s1中并记录时间 clock_t c0 = clock();for (int t : v)s.insert(t);clock_t cc = clock();//结束插入数据//把数据插入到s2中并记录时间 for (auto x : v)s1.insert(x);clock_t c1= clock();cout << "插入1百万数据:"<<endl; cout << " s1(负载因子设为0.1):" << c1 - cc << "毫秒" << endl;for (auto x : v)s2.insert(x);clock_t c2 = clock();cout << " s2(负载因子设为0.2):" << c2 - c1 << "毫秒" << endl;for (auto x : v)s3.insert(x);clock_t c3 = clock();cout << " s3(负载因子设为0.3):" << c3 - c2 << "毫秒" << endl;for (auto x : v)s4.insert(x);clock_t c4 = clock();cout << " s4(负载因子设为0.4):" << c4 - c3 << "毫秒" << endl;for (auto x : v)s5.insert(x);clock_t c5 = clock();cout << " s5(负载因子设为0.5):" << c5 - c4 << "毫秒" << endl;for (auto x : v)s6.insert(x);clock_t c6 = clock();cout << " s6(负载因子设为0.6):" << c6 - c5 << "毫秒" << endl;for (auto x : v)s7.insert(x);clock_t c7 = clock();cout << " s7(负载因子设为0.7):" << c7 - c6 << "毫秒" << endl;cout << " s (负载因子为默认值) :" << cc - c0 << "毫秒" << endl<<endl;//在s 中查询0~1,000,000并统计时间c0= clock();for (unsigned int i = 0; i < 1000000; i++)s.find(i);//不处理查询结果cc = clock();//在s1中查询0~1,000,000并统计时间for (unsigned int i = 0; i < 1000000; i++)s1.find(i);//不处理查询结果c1 = clock();for (unsigned int i = 0; i < 1000000; i++)s2.find(i);//不处理查询结果c2= clock();for (unsigned int i = 0; i < 1000000; i++)s3.find(i);//不处理查询结果c3 = clock();for (unsigned int i = 0; i < 1000000; i++)s4.find(i);//不处理查询结果c4 = clock();for (unsigned int i = 0; i < 1000000; i++)s5.find(i);//不处理查询结果c5 = clock();for (unsigned int i = 0; i < 1000000; i++)s6.find(i);//不处理查询结果c6 = clock();for (unsigned int i = 0; i < 1000000; i++)s7.find(i);//不处理查询结果c7 = clock();cout << "查询1百万数据:" << endl;cout<<"s (负载因子默认为1) :" << cc - c0 << "毫秒" << endl;cout << " s1(负载因子设为0.1):" << c1 - cc << "毫秒" << endl;cout << " s2(负载因子设为0.2):" << c2 - c1 << "毫秒" << endl;cout << " s3(负载因子设为0.3):" << c3 - c2 << "毫秒" << endl;cout << " s4(负载因子设为0.4):" << c4 - c3 << "毫秒" << endl;cout << " s5(负载因子设为0.5):" << c5 - c4 << "毫秒" << endl;cout << " s6(负载因子设为0.6):" << c6 - c5 << "毫秒" << endl;cout << " s7(负载因子设为0.7):" << c7 - c6 << "毫秒" << endl;cout << "s默认的最大负载因子:" << s.max_load_factor() << endl;cout << "s实际的负载因子:" << s.load_factor() << endl;cout << "s1设置的最大负载因子:" << s1.max_load_factor() << endl;cout << "s1实际的负载因子:" << s1.load_factor() << endl;cout << "s2默认的最大负载因子:" << s2.max_load_factor() << endl;cout << "s2实际的负载因子:" << s2.load_factor() << endl;cout << "s3默认的最大负载因子:" << s3.max_load_factor() << endl;cout << "s3实际的负载因子:" << s3.load_factor() << endl;cout << "s4默认的最大负载因子:" << s4.max_load_factor() << endl;cout << "s4实际的负载因子:" << s4.load_factor() << endl;cout << "s5默认的最大负载因子:" << s5.max_load_factor() << endl;cout << "s5实际的负载因子:" << s5.load_factor() << endl;cout << "s6默认的最大负载因子:" << s6.max_load_factor() << endl;cout << "s6实际的负载因子:" << s6.load_factor() << endl;cout << "s7默认的最大负载因子:" << s7.max_load_factor() << endl;cout << "s7实际的负载因子:" << s7.load_factor() << endl;return 0;
}

输出结果:

由结果我们得出:修改默认的负载因子时

对于插入的执行影响较大,当负载因子过小时,执行时间为最佳执行时间的两倍;

对于查找的执行效率影响较小

使用默认的负载因子效率极为贴近最佳的执行效率

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/330557.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

炫酷gdb

在VS里面调试很方便对吧&#xff1f;&#xff08;F5直接调试&#xff0c;F10逐过程调试--不进函数&#xff0c;F11逐语句调试--进函数&#xff0c;F9创建断点&#xff09;&#xff0c;那在Linux中怎么调试呢&#xff1f; 我们需要用到一个工具&#xff1a;gdb 我们知道VS中程…

可转债日内自动T+0交易,行情推送+策略触发+交易接口

说明 目前这个项目已编译打包,下载即可测试,直接生成多平台可执行文件&#xff0c;详见运行方法。行情部分与策略弱相关&#xff0c;拆分解耦单独作为一个项目。行情项目请移步GitHub - freevolunteer/hangqing: A股行情订阅工具&#xff0c;支持股票/可转债level2/level2数据&…

【系统架构师】-案例篇(十五)SOA、微服务与数据库

1、可复用构件应具备哪些属性 可用性&#xff1a;构件必须易于理解和使用。 质量&#xff1a;构件及其变形必须能正确工作。 适应性&#xff1a;构件应该易于通过参数化等方式在不同语境中进行配置。 可移植性&#xff1a;构件应能在不同的硬件运行平台和软件环境中工作。 可变…

设计模式14——组合模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 组合模式&#xff08;Composit…

废物回收机构|基于SprinBoot+vue的地方废物回收机构管理系统(源码+数据库+文档)

地方废物回收机构管理系统 目录 基于SprinBootvue的地方废物回收机构管理系统 一、前言 二、系统设计 三、系统功能设计 1管理员功能模块 2 员工功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍…

【minio】minio文件访问不到问题记录

问题描述&#xff1a; 项目上上传了logo&#xff0c;但是无法回写logo&#xff0c;但是文件minio路径已经返回&#xff0c;并且到minio服务器上也能下载文件&#xff1b; 解决方案&#xff1a; 1.排查Nginx的代理的minio是否正确 2.登录minio服务查一下文件路径policy是否设置访…

在某云服务器上搭建公网kali linux2.0

前提&#xff1a; 可用的 CVM 实例 挂载一个系统盘之外的盘&#xff0c;安装完成后可卸载&#xff01; 创建实例&#xff0c;安装centos7系统&#xff01; 然后执行fdisk -l看磁盘的情况 在这里我将把镜像写入vdb这块数据盘 非 root 的情况下记得sudo执行以下命令 注意&…

机器学习之常用算法与数据处理

一、机器学习概念&#xff1a; 机器学习是一门多领域交叉学科&#xff0c;涉及概率论、统计学、计算机科学等多门学科。它的核心概念是通过算法让计算机从数据中学习&#xff0c;改善自身性能。机器学习专门研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识…

jmeter保存测试计划报错——Couldn‘t save test plan to file:

jmeter保存测试计划报错——Couldnt save test plan to file:。。。。。拒绝访问 一、问题描述二、分析三、结果 一、问题描述 Couldn’t save test plan to file:D:\Program Files\apache-jmeter-5.6.2\bin\线程组.jmx D:\Program Files\apache-jmeter-5.6.2\bin\线程组.jmx(…

用WPS将多张图片生成一个pdf文档,注意参数设置

目录 1 新建一个docx格式的文档 2 向文档中插入图片 3 设置页边距 4 设置图片大小 5 导出为pdf格式 需要把十几张图片合并为一个pdf文件&#xff0c;本以为很简单&#xff0c;迅速从网上找到两个号称免费的在线工具&#xff0c;结果浪费了好几分钟时间&#xff0c;发现需要…

【汽车操作系统】Autosar和商用OS

目录 什么是AUTOSAR? CP AUTOSAR架构 CAN通信 AP AUTOSAR 背景 CP&AP 开发方面的不同&#xff1a; WRLinux介绍 QNX介绍 什么是AUTOSAR? 随着汽车功能越来越多&#xff0c;导致ECU的数量越来越多。1993年的时候&#xff0c;奥迪A8才只有5个ECU现在典型的现代汽车…

shell文本三剑客——awk命令【☆】

目录 一、akw原理 二、命令格式 三、常用变量 四、awk的用法 1.输出整行内容 2.按字段输出文本内容 3.按列输出文件内容 FS变量为列分隔符 4.awk的三个模式 5. awk ‘控制语句条件 {操作}’ 文件 6.awk的数组 7.awk的应用 一、akw原理 逐行读取文本&#xff0c;默认…

TypeScript-泛型

泛型(Generics) 指在定义接口&#xff0c;函数等类型的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性&#xff0c;使用泛型可以复用类型并且让类型更加灵活 泛型接口-interface 语法&#xff1a;在 interface 接口类型的名称后面使用…

《基于Jmeter的性能测试框架搭建》改进一

《基于Jmeter的性能测试框架搭建》文末笔者提到了不少待改进之处&#xff0c;如下所示。 Grafana性能图表实时展现&#xff0c;测试过程中需实时截图形成测试报告&#xff0c;不够人性化。解决方案&#xff1a;自动生成测试报告并邮件通知。 Grafana性能图表需测试人员实时监控…

加入MongoDB AI创新者计划,携手MongoDB共同开创AI新纪元

加入MongoDB AI创新者计划&#xff01; MongoDB对AI创新和初创企业的支持既全面又广泛&#xff01;无论您是领先的AI初创企业还是刚刚起步&#xff0c;MongoDB Atlas都是支持您愿景的最佳平台。 AI 初创者计划The AI Startup Track AI初创者计划为早期初创企业提供专属福利&…

云端漫步:搭建个人博客的移动云之旅

&#x1f482;作者简介&#xff1a; Thunder Wang&#xff0c;阿里云社区专家博主&#xff0c;华为云云享专家&#xff0c;腾讯云社区认证作者&#xff0c;CSDN SAP应用技术领域优质创作者。在学习工作中&#xff0c;我通常使用偏后端的开发语言ABAP&#xff0c;SQL进行任务的完…

dmanywhere的docker制作

dmanywhere的docker制作 官网地址&#xff1a; http://www.dmanywhere.cn/ 下载相关执行文件。 Dockerfile的默认命名是“Dockerfile”&#xff0c; 在构建镜像时&#xff0c;如果没有指定Dockerfile文件&#xff0c;Docker通常会寻找名为“Dockerfile”的文件 1.Dockerf…

6款网站登录页(附带源码)

6款网站登录页 效果图及部分源码123456 领取源码下期更新预报 效果图及部分源码 1 部分源码 <style>* {margin: 0;padding: 0;}html {height: 100%;}body {height: 100%;}.container {height: 100%;background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);}.l…

搜索引擎的设计与实现(四)

目录 6 系统测试 6.1测试重要性 6.2测试用例 结 论 参 考 文 献 前面内容请移步 搜索引擎的设计与实现&#xff08;三&#xff09; 免费源代码&毕业设计论文 搜索引擎的设计与实现 6 系统测试 6.1测试重要性 该项目是在本地服务器上进行运行和调试&#xff0c;…

Spring6基础笔记

Spring6 Log4j2 1、概述 1.1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发…