STL好难(8):map和set

news2024/10/7 6:44:53

目录

1.一些概念的理解

🍉关联式容器和序列式容器

🍉key模型、key/value模型

🍉树形结构关联式容器

2.set的介绍

🍉set文档

🍉set的使用

🍒set的模板参数列表

🍒set的构造

🍒set的迭代器

🍒set的容量

🍒set的修改操作

3.multiset介绍

🍉set文档

🍉multiset的使用

🍒构造列表

🍒各类函数接口:

🍒multiset 和 set 的区别

4.map的介绍

🍉map文档

🍉map的使用

🍒map的模板参数说明

🍒map构造

🍒map的迭代器

🍒map的容量与元素访问

🍒map中元素的修改

🦁map的插入方法

🦁map里面数据的打印

🦁map的覆盖问题

🦁map中operator[ ] 的应用

🦁map中operator[ ] 的原理

🍉map总结

5.multimap的介绍

🍉multimap的文档介绍:

🍉multimap的使用

6.在OJ中的使用

🍉前k个高频单词

🍉两个数组的交集


1.一些概念的理解

🍉关联式容器和序列式容器

在STL学习中,我们接触过STL中的部分容器,比如:vector、list、deque、等等,这些容器统称为序列式容器,因为其底层为线性数据结构,里面存储的是元素本身。

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

🍉key模型、key/value模型

key模型

如门禁系统、车壳系统、检测一篇文章中单词拼写是否正确等等

key模型主要是用于对单一元素进行查找比较用的

key/value模型(键值对)

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

比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义

SGI-STL中关于键值对的定义:

用 pair 来命名的结构体

template <class T1, class T2>
struct pair
{
	typedef T1 first_type;
	typedef T2 second_type;
	T1 first;
	T2 second;
	pair() : first(T1()), second(T2())
	{}
	pair(const T1& a, const T2& b) : first(a), second(b)
	{}
};

🍉树形结构关联式容器

根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。

树型结构的关联式容器主要有四种:map、set、multimap、multiset

这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。

2.set的介绍

🍉set文档

点击查看set文档内容

翻译:

  • 1. set是按照一定次序存储元素的容器
  • 2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  • 3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  • 4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
  • 5. set在底层是用二叉搜索树(红黑树)实现的。

注意:

  • 1. 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放value,但在底层实际存放的是由<value, value>构成的键值对。
  • 2. set中插入元素时,只需要插入value即可,不需要构造键值对。
  • 3. set中的元素不可以重复(因此可以使用set进行去重)。
        (因为set本身是有序的,可以做到去重加排序)
  • 4. 使用set的迭代器遍历set中的元素,可以得到有序序列
  • 5. set中的元素默认按照小于来比较(小的在前,大的在后)
  • 6. set中查找某个元素,时间复杂度为:$log_2 n$
  • 7. set中的元素不允许修改(因为修改元素后不能保证元素的有序)
  • 8. set中的底层使用二叉搜索树(红黑树)来实现。

🍉set的使用

🍒set的模板参数列表

T : set中存放元素的类型,实际在底层存储<value, value>的键值对。
Compare:set中元素默认按照小于来比较
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理

🍒set的构造

函数声明功能介绍
set (const Compare& comp = Compare(), const Allocator& = Allocator() );构造空的set
set ( InputIterator first, InputIterator last, const Compare& comp = Compare( ), const Allocator& = Allocator( )  );

用 [first, last] 区间中的元素构造set

set ( const set<Key,Compare,Allocator>& x);set的拷贝构造

代码示例如下:

#include<iostream>
#include<set>
#include<vector>
using namespace std;

int main()
{
	vector<int> v = { 3,8,3,5,7,1,1,2,1 };

	//构建空的set,s1
	set<int> s1;

	//用区间构建set
	set<int> s2(v.begin(), v.end());

	//set的拷贝构造
	set<int> s3(s2);

	//范围for打印
	for (auto e : s2)
	{
		cout << e << " ";
	}
	cout << endl;

	for (auto e : s3)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

得到结果:

可以看到打印结果是:排序+去重

注意:对于set来说,里面的元素是不能修改的

 

因为set的底层是搜索树,随意修改会失去搜索树的意义

🍒set的迭代器

解释如下:

函数声明功能介绍
iterator begin()返回set中起始位置元素的迭代器
iterator end()返回set中最后一个元素后面的迭代器
const_iterator cbegin() const返回set中起始位置元素的const迭代器
const_iterator cend() const返回set中最后一个元素后面的const迭代
reverse_iterator rbegin()返回set第一个元素的反向迭代器,即end
reverse_iterator rend()返回set最后一个元素下一个位置的反向迭代器, 即rbegin
const_reverse_iterator crbegin() const返回set第一个元素的反向const迭代器,即cend
const_reverse_iterator crend() const返回set最后一个元素下一个位置的反向const迭 代器,即crbegin

迭代器的使用方法和之前的容器使用都差不多相同,这里就不多介绍了

🍒set的容量

函数声明功能介绍
bool empty ( ) const检测set是否为空,空返回true,否则返回true
size_type size() const返回set中有效元素的个数

max_size 返回的是set的最大容量,用的很少 

代码示例如下:

int main()
{
	vector<int> v = { 3,8,3,5,7,1,1,2,1 };

	//用区间构建set
	set<int> s2(v.begin(), v.end());

	//范围for打印
	for (auto e : s2)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << s2.empty() << endl;
	cout << s2.size() << endl;

	return 0;
}

🍒set的修改操作

函数声明功能介绍
pair insert ( const value_type& x )

在set中插入元素x,实际插入的是<x, x>构成的键值对

如果插入成功,返回<该元素在set中的位置,true>,

如果插入失败,说明x在set中已经存在,
返回<x在set中的位置,false>

void erase ( iterator position )删除set中position位置上的元素
size_type erase ( const key_type& x )删除set中值为x的元素,返回删除的元素的个数
void erase ( iterator first, iterator last )删除set中[first, last)区间中的元素
void swap ( set<Key,Compare,Allocator>& st );交换set中的元素
void clear ( )将set中的元素清空
iterator find ( const key_type& x ) const返回set中值为x的元素的位置
size_type count ( const key_type& x ) const返回set中值为x的元素的个数(由于set里面没有重复变量,所以count就是看这个值在不在)

代码示例:

#include <set>
void TestSet()
{
	// 用数组array中的元素构造set
	int array[] = { 1, 3, 5, 7, 9, 2, 8, 0, 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	set<int> s(array, array + sizeof(array) / sizeof(array));
	cout << s.size() << endl;

	// 正向打印set中的元素,从打印结果中可以看出:set可去重
	for (auto& e : s)
		cout << e << " ";
	cout << endl;

	// 使用迭代器逆向打印set中的元素
	for (auto it = s.rbegin(); it != s.rend(); ++it)
		cout << *it << " ";
	cout << endl;

	// set中值为3是否存在
	cout << s.count(3) << endl;
}

3.multiset介绍

🍉set文档

multiset文档介绍

multiset和set基本一致,只是multiset可以插入重复的元素

翻译:

  • 1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
  • 2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。
  • 3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。
  • 4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。
  • 5. multiset底层结构为二叉搜索树(红黑树)。

注意:

  • 1. multiset中再底层中存储的是<value, value>的键值对
  • 2. mtltiset的插入接口中只需要插入即可
  • 3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的
  • 4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列
  • 5. multiset中的元素不能修改
  • 6. 在multiset中找某个元素,时间复杂度为$O(log_2 N)$
  • 7. multiset的作用:可以对元素进行排序

🍉multiset的使用

和set的使用方法基本一致,可以参考set的使用来学习

🍒构造列表

T : set中存放元素的类型,实际在底层存储<value, value>的键值对。
Compare:set中元素默认按照小于来比较
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理

🍒各类函数接口:

下面只展示一部分接口,更多接口可以查看文档

 

🍒multiset 和 set 的区别

根据set的内容学习,我们可以直到set是可以去重和排序的

multiset只是利用搜索二叉树完成排序,不会进行去重

如下代码演示:

void test1()
{
	vector<int> v = { 3,8,3,5,7,1,1,2,1 };

	set<int> s(v.begin(), v.end());

	multiset<int> ms(v.begin(), v.end());

	//范围for打印
	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	for (auto e : ms)
	{
		cout << e << " ";
	}
	cout << endl;
}

还要注意一点,就是函数count()的区别

对于set来说,count仅仅是查看这个数在不在搜素二叉树里面,这时因为set里面只能存放不重复的树,有就只能是1,

而对于 multiset 来说,他可以存放重复的数,所以此时count()返回的是总个数

 如下:

 

4.map的介绍

🍉map文档

map的文档介绍

翻译:

  • 1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
  • 2. 在map中,键值key通常用于排序和惟一地标识元素而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,
    为其取别名称为pair: typedef pair<const key, T> value_type;
  • 3. 在内部,map中的元素总是按照键值key进行比较排序的。
  • 4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
  • 5. map支持下标访问符,即在[ ]中放入key,就可以找到与key对应的value。
  • 6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

🍉map的使用

学习map之前我们再来回顾一下上面提到的 结构pair

 

🍒map的模板参数说明

key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器

注意:在使用map时,需要包含头文件#include<map>

🍒map构造

函数声明功能介绍
map()构造一个空的map

🍒map的迭代器

函数声明功能介绍
begin()和end()begin:首元素的位置,end最后一个元素的下一个位置
cbegin()和cend()与begin和end意义相同,但cbegin和cend所指向的元素不 能修改
rbegin()和rend()反向迭代器,rbegin在end位置,rend在begin位置,其 ++和 -- 操作与begin和end操作移动相反
crbegin()和crend()与rbegin和rend位置相同,操作相同,但crbegin和crend所 指向的元素不能修改

🍒map的容量与元素访问

 主要介绍3个:

函数声明功能介绍

empty

bool empty ( ) const
检测map中的元素是否为空,是返回 true,否则返回false

size

size_type size() const
返回map中有效元素的个数

operator[]

mapped_type& operator[] (const key_type& k)
返回去key对应的value

🍒map中元素的修改

函数声明功能介绍
pair insert ( const value_type& x )

在map中插入键值对x,注意x是一个键值对,

返回值也是键值对:iterator代表新插入元素的位置,bool代表释放插入成功

void erase ( iterator position )删除position位置上的元素
size_type erase ( const key_type& x )删除键值为x的元素
void erase ( iterator first, iterator last )删除[first, last)区间中的元素
void swap ( map<Key,T,Compare,Allocator>& mp )交换两个map中的元素
void clear ( )将map中的元素清空
iterator find ( const key_type& x )在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end
const_iterator find ( const key_type& x ) const在map中插入key为x的元素,找到返回该元素的位置的const迭代器,否则返回cend
size_type count ( const key_type& x ) const返回key为x的键值在map中的个数,注意 map 中key是唯一的,因此该函数的返回值 要么为0,要么为1,因此也可以用该函数来 检测一个key是否在map中

map的大多数使用方法和set差不多,下面我们说一些不要重要的部分:

🦁map的插入方法

#include<map>
int main()
{
	// 构造map对象dict,底层容器为string
	map<string, string> dict;

	// 插入方式1:利用piar的结构体,使用其匿名对象进行插入
	dict.insert(pair<string, string>("stick", "栈"));

	// 插入方式2:利用make_pair进行插入(一般都用这个)
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("count", "计数"));

    return 0;
}

里面提到的 make_pair 如下:是一个模板函数会自动识别传来的参数将其转化为pair的匿名对象

🦁map里面数据的打印

	//map<string, string>::iterator dit = dict.begin();
	auto dit = dict.begin();
	while (dit != dict.end())
	{
		// 方法一:用指针解引用去访问
		cout << (*dit).first << ":" << (*dit).second << endl;
		++dit;
	}
	cout << endl;

	auto dit = dict.begin();
	while (dit != dict.end())
	{
		// 方法二:直接用箭头指向(本来应该要有两个箭头,这里会省略一个,使其更简洁)
		cout << dit->first << ":" << dit->second << endl;
		++dit;
	}
	cout << endl;

🦁map的覆盖问题

#include<map>
int main()
{
	// 构造map对象dict,底层容器为string
	map<string, string> dict;

	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("count", "计数"));
	
	// 我们再插入一个string类型,value值设为不同
	dict.insert(make_pair("string", "**字符串"));
}

提问:此时我们的 map 里面应该存的是哪一个value呢?

我们打印来看看:

 可以看到结果是插入失败

🦁map中operator[ ] 的应用

我们用map来统计一下水果出现的次数

代码如下:

int main()
{
	string arr[] = { "西瓜", "西瓜", "苹果", "西瓜", "苹果", 
		"苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉", "梨" };
	
	// 统计水果出现的次数
	map<string, int> countMap;
	for (auto& e : arr)
	{
		auto ret = countMap.find(e);
		// ret == countMap.end()说明没找到,水果第一次出现
		if (ret == countMap.end())
		{
			// 第一次出现,插入value,让其等于1
			countMap.insert(make_pair(e, 1));
		}
		else
		{
			// 找到了,就对value++
			ret->second++;
		}
	}

	// 打印
	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}

    return 0;
}

我们在记录出现水果次数时,上面那样写代码还是比较繁琐,我们可以直接容operator[ ]来解决:

代码如下:

void test4()
{
	string arr[] = { "西瓜", "西瓜", "苹果", "西瓜", "苹果", 
		"苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉", "梨" };

	map<string, int> countMap;

	// 统计
	for (auto& e : arr)
	{
		countMap[e]++;
	}

	// 打印
	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
}

map最值得我们学习的就是这里的operator[ ]

当然,operator[ ] 在插入时也可以用,示例如下:

int main()
{
	map<string, string> dict;

	dict.insert(pair<string, string>("stick", "栈"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("count", "计数"));

	dict["left"];					// 插入
	dict["right"] = "右边";			// 插入+修改
	dict["string"] = "**字符串";	// 修改
	cout << dict["string"] << endl;	// 查找
    
    return 0;
}

🦁map中operator[ ] 的原理

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

  用<key, T()>构造一个键值对,然后调用 insert() 函数将该键值对插入到map中
  如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器
  如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器
  operator[ ] 函数最后将insert返回值键值对中的value返回

🍉map总结

  • 1. map中的的元素是键值对
  • 2. map中的key是唯一的,并且不能修改
  • 3. 默认按照小于的方式对key进行比较
  • 4. map中的元素如果用迭代器去遍历,可以得到一个有序的序列
  • 5. map的底层为平衡搜索树(红黑树),查找效率比较高$O(log_2 N)$
  • 6. 支持[]操作符,operator[]中实际进行插入查找

5.multimap的介绍

🍉multimap的文档介绍:

multimap的文档介绍

翻译:

  • 1. Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对
    <key, value>,其中多个键值对之间的key是可以重复的。
  • 2. 在multimap中,通常按照key排序和惟一地标识元素,而映射的value存储与key关联的内容。key和value的类型可能不同,通过multimap内部的成员类型value_type组合在一起,value_type是组合key和value的键值对:typedef pair<const Key, T> value_type;
  • 3. 在内部,multimap中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对key进行排序的。
  • 4. multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代器直接遍历multimap中的元素可以得到关于key有序的序列。
  • 5. multimap在底层用二叉搜索树(红黑树)来实现。

注意:
multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的

🍉multimap的使用

参考map的使用方法就行,更能都是类似的

需要注意的是:

  • 1. multimap中的key是可以重复的。
  • 2. multimap中的元素默认将key按照小于来比较
  • 3. multimap中没有重载operator[]操作
  • 4. 使用时与map包含的头文件相同
#include<map>

int main()
{
	multimap<string, string> dict;

	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("count", "计数"));
	// 重复插入一个string
	dict.insert(make_pair("string", "**字符串"));

	auto dit = dict.begin();
	while (dit != dict.end())
	{
		cout << dit->first << ":" << dit->second << endl;
		++dit;
	}
	cout << endl;
    
    return 0;
}

可以看到 multimap 是允许 键值冗余 的

value值相同也是允许的

 

6.在OJ中的使用

🍉前k个高频单词

思路:

我们要注意,题目要求 i 必须在 love 之前,这就需要我们排序时需要保证其稳定性

做这道题的时候,我们可以首先将其利用map来统计次数,然后将其放到vector里面,
之后再用一个稳定排序算法对其进行排序,选出前k个最大的,

在这些算法中,我们常用的 sort() 函数,其底层原理是快排,是不稳定的

我们可以用到库里面提供的一个稳定排序:stable_sort(),其底层是归并排序

具体步骤可以看下面代码的注释:

class Solution {
public:
    struct Compare
    {
        bool operator()(const pair<string, int>& kv1, const pair<string, int>& kv2)
        {
            return kv1.second > kv2.second;
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) 
    {
        map<string, int> countMap;
        // 统计次数
        for(auto& str : words)
        {
            countMap[str]++;
        }

        //由于map是一个双向迭代器,sort需要随机迭代器,
        //所以我们需要将统计好的数,放到vector里面进行排序
        vector<pair<string, int>> v(countMap.begin(), countMap.end());

        //这里的sort是按pair去比的,
        //pair里面的比较大小不适合我们这道题(可以去看文档说明)
        //这里我们需要的是按second,这时我们就需要用到之前写的仿函数了
        stable_sort(v.begin(), v.end(), Compare());

        //取前k个数的first存到vv里面
        vector<string> vv;
        for(int i = 0; i < k; ++i)
        {
            vv.push_back(v[i].first);
        }

        return vv;
    }
};

当然我们除了用stable_sort来使排序稳定,也可以再仿函数里面进行操作使其稳定,如下:

//我们就用sort只是需要再仿函数里面加上一个first的比较
struct Compare
{
    bool operator()(const pair<string, int>& kv1, const pair<string, int>& kv2)
    {
        return kv1.second > kv2.second || (kv1.second == kv2.second && kv1.first < kv2.first);
    }
};

思路2:

我们可不可以不用sort进行排序呢?

这里我们可以采用multiset进行排序,并利用仿函数达到我们想要的排序效果

class Solution {
public:
    //sort仿函数和multiset的仿函数逻辑一样
    struct Compare
    {
        bool operator()(const pair<string, int>& kv1, const pair<string, int>& kv2) const
        {
            return kv1.second > kv2.second || (kv1.second == kv2.second && kv1.first < kv2.first);
        }
    };

    vector<string> topKFrequent(vector<string>& words, int k) 
    {
        map<string, int> countMap;
        // 统计次数
        for(auto& str : words)
        {
            countMap[str]++;
        }

        //这里不要用map,因为map是去重加排序,也不能用multimap,multimap只会对key进行排序
        //我们这里采用multiset来对pair的first和second进行仿函数的比较操作
        multiset<pair<string, int>, Compare> sortSet(countMap.begin(), countMap.end()); 

        //取前k个放到arr里面
        vector<string> arr;
        auto it = sortSet.begin();
        while(k--)
        {
            arr.push_back(it->first);
            it++;
        }

        return arr;
    }
};

🍉两个数组的交集

首先要做的是排序+去重

去重操作,我们的算法库里面也给出了:unique去重算法

此时我们可以用sort + unique解决,也可以用我们学的set来解决

当然,我们的算法库也有求交集和差集的算法:

set_intersection找交集        set_difference找差集        set_union找并集

我们在这里就不去调这些算法来解了,我们自己来写

代码如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        // 排序+去重
        // sort(nums1.begin(), nums1.end());
        // unique(nums1.begin(), nums1.end());
        set<int> s1(nums1.begin(), nums1.end());
        set<int> s2(nums2.begin(), nums2.end());

        auto it1 =s1.begin();
        auto it2 =s2.begin();
        
        vector<int> v;
        while(it1 != s1.end() && it2 != s2.end())
        {
            if(*it1 < *it2)
            {
                ++it1;
            }
            else if(*it2 < *it1)
            {
                ++it2;
            }
            else
            {
                v.push_back(*it1);
                ++it1;
                ++it2;
            }
        }
        return v;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【TiDB理论知识 05】TiKV-Raft协议

目录 一 概念 二 raft共识算法对于TiKV的几个重要功能 1 Raft日志复制 1 Raft日志复制流程 2 名词解释 分层次理解TIKV 2 Raft Leader选举 集群初始状态时Leader选举流程 数据正在复制时Leader选举流程 初始化时的特殊情况 raft 参数与Tidb 参数对应关系 一 概念 le…

SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

在SpringCloud系列&#xff08;十五&#xff09;[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解, 并且已经将一些数据进行了存储, 但是这并不是我们学习 ElasticSearch 的目的, ElasticSearch 最擅长的…

Java8之Stream流

目录 简介 特点 Stream操作步骤 创建 中间操作 筛选与切片 filter(Predicate p) distinct() limit(long maxSize) skip(long n) 映射 map(Function f) flatMap(Function f) 排序 自然排序 定制排序 终止操作 匹配与查找 归约 收集 好处 不足 简介 在编写…

css基本样式的使用

1、高度和宽度 .c1{height: 300px;width: 500px; }注意事项&#xff1a; 宽度&#xff0c;支持百分比行内标签&#xff0c;默认无效块级标签&#xff0c;默认有效&#xff08;即使右侧空白&#xff0c;也不给你占用&#xff09; 块级和行内标签 css样式 标签&#xff1a; di…

echarts 地图点击常见问题

echats 散点图不支持缩放 echarts 地图点击激活label如何去除 高德loca 1.4版本热力图报错 绘制的颜色区间是 0 --1 高德地图销毁不生效 自己傻逼&#xff0c;每次没有清空数组导致叠加数据&#xff0c;约点数据越多。 为何用高德地图district.search查询不到别的省数据&…

【SpringBoot】SpringBoot的创建和运行

1.什么是SpringBoot&#xff1f; Spring 的诞⽣是为了简化 Java 程序的开发的&#xff0c;⽽ Spring Boot 的诞⽣是为了简化 Spring 程序开发 的。 Spring Boot是由Pivotal团队提供的基于Spring的框架&#xff0c;该框架使用了特定的方式来进行配置&#xff0c;从而使开发…

洗鞋小程序开发

上门洗鞋小程序为用户提供了便捷、高效的鞋子洗护服务。通过手机即可预约上门取送鞋子&#xff0c;省时省力&#xff0c;让鞋子焕然一新。下面我们来看看这个小程序的具体功能介绍。 1. 预约取送服务&#xff1a;用户可以在上门洗鞋小程序中选择合适的时间和地点&#xff0c;预…

访问学者面试申请如何应对?

作为一个学者面试申请者&#xff0c;面对这一重要机会&#xff0c;我们需要认真准备并采取适当的应对策略。下面知识人网小编将提供一些建议&#xff0c;帮助你在面试中取得良好的表现。 首先&#xff0c;在准备阶段&#xff0c;你应该研究并了解申请机构的背景和研究方向。了解…

阻止冒泡 大盒子套小盒子 点击大盒子跳转页面 小盒子不跳转

比如论坛点赞功能 点击这篇帖子跳到论坛详情页面,但是点赞不跳转 <view click.stop"onSmallBoxClick"><!-- 点赞 --> </view>methods: {onSmallBoxClick() {// 点赞逻辑 } } 大盒子 帖子div <view click"g…

pdf合并一页怎么合并?这几种合并方法看看

pdf合并一页怎么合并&#xff1f;PDF文件是一种非常常见的文件格式&#xff0c;它可以在不同的操作系统和设备之间方便地进行共享。有时候&#xff0c;我们需要将多个PDF文件合并成一个文件。例如&#xff0c;当我们需要将多个文档合并成一个大文档时&#xff0c;或者我们需要将…

Redis数据类型与常用命令

文章目录 前言一、Redis数据类型1. Redis数据类型简介2. Redis数据类型特点 二、Redis常用命令1. 字符串string 操作命令2. 哈希hash 操作命令3. 列表list 操作命令4. 集合set操作命令5. 有序集合 sorted set 操作命令6. 通用命令 总结 前言 为了巩固所学的知识&#xff0c;作…

TRT3-trt-basic - 6 Int8的量化

int8量化是利用int8乘法替换float32乘法实现性能加速的一种方法 对于常规模型有&#xff1a;y kx b&#xff0c;此时x、k、b都是float32, 对于kx的计算使用float32的乘法 对于int8模型有&#xff1a;y tofp32(toint8(k) * toint8(x)) b&#xff0c;其中int8 * int8结果为in…

win7,win10下删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\报错

在调试虚拟网卡驱动时&#xff0c;由于修改错误&#xff0c;导致枚举顺序错乱&#xff0c;因此通过删除HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\Root\WINTUN下的所有项&#xff0c;即可&#xff0c;win10可用。 1、下载PStools&#xff1a; http://technet.microsoft.c…

130、仿真-基于51单片机智能窗户温湿度电机控制仿真设计(Proteus仿真+程序+配套资料等)

方案选择 单片机的选择 方案一&#xff1a;STM32系列单片机控制&#xff0c;该型号单片机为LQFP44封装&#xff0c;内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ&#xff0c;在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节…

算法(1):斐波那契数列模型

目录 &#x1f981;三步问题 &#x1f349;题目解析 &#x1f349;算法原理 &#x1f352;状态表示 &#x1f352;状态转移方程 &#x1f352;初始化 &#x1f352;填表顺序、返回值 &#x1f349;代码编写 &#x1f981;使用最小花费爬楼梯 &#x1f349;题目解析 …

为什么选择STM32才是明智之选?

在电子工程领域&#xff0c;我们强调适用性&#xff0c;性能并非最重要&#xff0c;甚至不是首要考虑因素。选择合适的微控制器&#xff08;MCU&#xff09;根据设计需求而异&#xff0c;常规做法是在保证功能满足的前提下&#xff0c;选择稳定可靠且经济实惠的器件。而对于那些…

前端转换bigInt,axios拦截器失效

前端转换bigInt&#xff0c;axios拦截器失效 关于bigInt的使用切换雪花ID解决精度丢失问题进度丢失&#xff0c;前端不支持bigInt解决问题 拦截器失效验证及解决 关于bigInt的使用 这篇文章算是使用中的小笔记吧&#xff0c;主要是我自己搜索没找到直接的方法&#x1f613;&am…

SSH隧道功能

随着互联网的普及和发展&#xff0c;越来越多的企业需要申请公网IP地址。&#xff08;公网IP地址是指可以在互联网上直接访问的P地址&#xff0c;可以用于建立网站、远程办公、视频监控等应用。&#xff09; 而公网IP费用较高&#xff0c;笔者在某搜索软件上搜了一下&#xff…

科研创新服务平台性能分析案例

前言 信息中心老师反应&#xff0c;用户反馈科研创新服务器平台有访问慢的情况&#xff0c;需要通过流量分析系统来了解系统的运行情况&#xff0c;此报告专门针对系统的性能数据做了分析。 信息中心已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和历史原…

笑谈测试员躺着也中枪的那些事

在近9年的软件测试职业生涯中&#xff0c;多少遇到一些奇奇怪怪的事。而最悲催的莫过于那些自己躺着也中枪的事&#xff0c;如果处理不好惹火烧身&#xff0c;直接被“毙掉”也不无可能。 下面就摆摆那些事儿(其中可能因人老记忆衰退严重&#xff0c;与事实间有一定的夸大成分&…