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

【C++】map、set、multimap、multiset的介绍和使用

我讨厌世俗,也耐得住孤独。

在这里插入图片描述

文章目录

  • 一、键值对
  • 二、树形结构的关联式容器
    • 1.set
      • 1.1 set的介绍
      • 1.2 set的使用
      • 1.3 multiset的使用
    • 2.map
      • 2.1 map的介绍
      • 2.2 map的使用
      • 2.3 multimap的使用
  • 三、两道OJ题
    • 1.前K个高频单词(less<T>小于号是小的在左面升序,greater<T>大于号是大的在左面降序)
    • 2.两个数组的交集(排序+去重,简单的比对算法)



一、键值对

1.
之前所学的vector,list,deque等容器都是序列式容器,因为他们的底层数据结构都是线性的,并且数据结构中存储的都是元素数据本身,也就是单一的变量。
而下面所学的set、map、multimap、multiset等容器都是关联式容器,他们内部存储的不再是单一的元素数据,存储的而是<key,value>的键值对,由于每个键值对之间都有关联,所以其结构天生就具有优势,在数据检索时效率要比序列式容器高的多。

2.
那什么是键值对呢?键值对实际也是一个类,类里面对key和value数据进行了封装,key表示关键码,value表示与之对应的值,下面是SGI对于pair键值对结构体的定义:

3.
struct pair{}有两个构造函数,一个是无参的利用T1和T2类型的默认构造函数初始化出来的键值对,一个是T1和T2作为参数的构造函数。
另外pair还重载了两个运算符,用于键值对的等于和小于比较,小于比较时,优先比较first,如果first恰好满足x<y,则返回true。如果first之间相等,则比较失败返回false。如果first是x>y,那就继续比较second。
为了方便构造键值对,pair又另写了成员函数make_pair(),这个函数其实也是调用了构造函数,但在构造键值对的时候,省下我们自己去传T1和T2的类型了就。

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) {}template <class T1, class T2>
inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) { return x.first == y.first && x.second == y.second; 
}template <class T1, class T2>
inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) { return x.first < y.first || (!(y.first < x.first) && x.second < y.second); 
}template <class T1, class T2>
inline pair<T1, T2> make_pair(const T1& x, const T2& y) {return pair<T1, T2>(x, y);
}

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

根据应用场景的不同,STL总共实现了两种不同结构的管理式容器,一种是树型结构,一种是哈希结构,树型结构的关联式容器主要分为map、set、multimap、multiset。
这四种容器的共同点是都是用平衡搜索树(红黑树)作为底层结构

1.set

1.1 set的介绍

1.
在set中,key和value是同时被标识的,所以key就是value,正由于key就是value,所以set容器中的元素不允许被修改,每个元素都被const修饰,只能增insert删erase查find。

2.
set在比较时默认使用缺省的仿函数less< T >,所以一旦比较成功时,较小元素就被插入到左边,较大元素就被插入到右边,那么在中序遍历时,结果自然就是升序结果。如果改为greater< T >,则逻辑就会反过来,中序遍历结果就是降序。

在这里插入图片描述
3.
set与map不同的是,map存放的是真正的键值对<key,value>,而set中只放value,但在底层实际存放的是<key,key>的键值对。

在这里插入图片描述
4.
set不允许元素被修改,因为这会破坏搜索树的结构。

5.
set中不允许元素有重复,所以set和二叉搜索树比较像,一旦元素重复再进行插入时,情况就较为复杂,需要用到树的旋转等知识,不过multiset可以支持插入的元素重复。
在使用set迭代器进行遍历时,set的迭代器走的是中序遍历的顺序,每一个迭代器都指向对应位置的键值对,当然set容器的元素我们也可以叫做键值对,只不过key和value相等罢了。

6.
由于set中不允许有元素重复,所以将一段数据插入到set时,set所展现的功能是排序+去重。

1.2 set的使用

1.
set的insert有三个重载形式,较为常用的就是直接插入一个值和利用其他容器的迭代器区间构建出set容器。

在这里插入图片描述

2.
erase用于删除set中的某个元素,如果删除成功,则返回1,否则返回0,size_type是unsigned int typedef出来的。

在这里插入图片描述

3.
find用于查找set中某个元素val,找到就返回键值对对应的迭代器,否则就返回end迭代器。
算法库中也有find,但哪个find的效率明显要低于set类的find,因为一个是类似于二分查找,一个是暴力通过迭代器进行查找,一个是logN,一个是N

在这里插入图片描述
在这里插入图片描述

void test_set1()
{set<int,greater<int>> s;s.insert(3);s.insert(1);s.insert(4);s.insert(7);s.insert(2);s.insert(1);//set底层是二叉搜索树,当插入相同的值时会返回false,所以set是排序+去重set<int,greater<int>>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;for (auto e : s){cout << e << " ";}cout << endl;//auto pos = s.find(3);auto pos = find(s.begin(), s.end(), 3);//算法库的find其实就是利用迭代器进行查找,找不到就返回end()迭代器//上面这两行代码的查找结果相同,但34行的效率肯定更高一些,因为35行是暴力查找,34行借助搜索树的特性查找高度次//如果是平衡的搜索树,则效率是O(logN)。暴力查找的效率是O(N),即一个一个迭代器的遍历进行查找。if (pos != s.end()){s.erase(pos);}for (auto e : s){cout << e << " ";}cout << endl;cout << s.erase(10) << endl;//返回0表示没有删除cout << s.erase(1) << endl;//返回1表示删除//上面代码等价于find+erase,删除元素也是要先找再删,找到就删,没找到就直接返回。
}

1.3 multiset的使用

1.
multiset与set的唯一区别就是允许元素重复,其余并没有什么区别,所以用multiset进行排序时,仅仅只能排序,没有去重的效果。
在set中count可能没有什么用,因为每个键值对都只能出现一次,不允许元素重复,但count在multiset中就有用了,可以统计某个key在set中共出现了几次。

在这里插入图片描述

#include <set>
void TestSet()
{int array[] = { 2, 1, 3, 9, 6, 0, 5, 8, 4, 7 };// 注意:multiset在底层实际存储的是<int, int>的键值对multiset<int> s(array, array + sizeof(array)/sizeof(array[0]));for (auto& e : s)cout << e << " ";cout << endl;return 0;
}

2.
在set和multiset中都有lower_bound和upper_bound接口,bound是约束束缚的意思,可以用于set中某一上限和下限区间元素的删除,有一说一,这俩接口确实不常用。

在这里插入图片描述

2.map

2.1 map的介绍

1.
map存储的是key和value组成的键值对元素结构体,在比较时按照key来进行比较,下面源码我们可以看到key依旧是不允许被修改的,但其对应的value是可以被修改的。

在这里插入图片描述
2.
map中比较时比较的是key类型,但我们可以通过key找到value,这里多说一句,无论是map还是set,他们的迭代器走的都是中序的顺序。

在这里插入图片描述

2.2 map的使用

1.
map和set都有三个构造函数,其中无参构造函数最为常用,平常在使用map或set时,直接定义其对象即可,无须传参,大多数情况下都是这样。

在这里插入图片描述
在这里插入图片描述
2.
map和set在插入后都会返回一个键值对:
键值对的first是迭代器,其指向的是新插入键值对,若新插入键值对的key已经存在,则返回已经存在的key对应的键值对的迭代器,这是first的变化规则。
键值对的second是bool值,如果插入的key已经存在,则bool为false,否则bool为true。

在这里插入图片描述
3.
map的迭代器访问这里有讲究,由于其迭代器指向的是由key和value组成的键值对,那* it该获得哪个key和value的哪个值呢?set的迭代器指向的就只有key,所以* it直接返回key值即可。
对于map来说,*it拿到的是pair的对象,所以我们还需要再加一个.操作符才能访问pair对象里面的first和second值,但这样写起来有点麻烦,所以map的迭代器也重载了→操作符,→重载的函数会返回迭代器指向对象的地址,所以还应该再加个→访问first或second才对,但是编译器在这里做了优化,省略了一个箭头。(这部分其实在list迭代器那里就说过了,这里正好做一下复习)

4.
在map这里,如果我们用语法糖遍历map时,最好采用const引用,因为map中存的是键值对pair,不用引用就会发生赋值,会调用pair的赋值重载函数,代价比较大,为了提升效率建议采用const引用。(语法糖遍历拿到的值其实就是*it,在map这里就是pair对象,键值对)

int main()
{map<string, string> dict;dict.insert(pair<string, string>("苹果", "apple"));dict.insert(pair<string, string>("鸭梨", "pear"));dict.insert(pair<string, string>("西瓜", "watermelon"));dict.insert(make_pair("草莓", "strawberry"));//make_pair是一个函数模板,内部调用pair的构造函数,但隐式实例化可以减少代码dict["迭代器"] = "iterator";// 插入+修改dict["insert"];// key不在就是插入,value用string的默认构造dict.insert(pair<string, string>("鸭梨", "xxxx"));//这个插入不进去,搜索树的鸭梨已经存在了dict["insert"] = "插入";// insert已经存在,这里表示修改insert的value值cout << dict["insert"] << endl;//key已经存在,这里相当于查找,[]会返回关键码对应的value值,查找时必须确定key已经存在于mapmap<string, string>::iterator it = dict.begin();while (it != dict.end()){//如果结点定义成key和value两个变量,*it都不知道返回谁的值。所以返回pair对象,这样就可以访问两个值了//cout << (*it).first << ":" << (*it).second << endl;cout << it->first << ":" << it->second << endl;//底层是pair封装了value和key,并实现运算符重载it++;}for (const auto& kv : dict)//kv就相当于*it,取到的是map中存储的结构体对象pair//现在的kv已经不像以前一样,仅仅是个内置类型,而是一个结构体对象,结构体的对象进行赋值调用函数代价太大,所以我们用引用{cout << kv.first << ":" << kv.second << endl;}
}

5.
如果用map来统计水果出现的次数,我们采用的思路可以是,如果key不在,那就将键值对插入map,键值对的int初始值设置为1。如果key在,那就把key对应的value值+1,最后语法糖遍历一下map,就可以拿到中序遍历的结果,也就是统计出了水果出现的次数。

6.
另外还有一种非常骚的操作就是利用map的[ ]来统计次数,在前面了解了insert的返回值之后,再来理解map的[ ]调用成本就会低很多了,实际上[ ]带来的作用包括插入,查找,修改的功能,直接一个[ ]运算符重载包揽map的三个重要功能。

7.
拥有这么多功能其实还是因为调用了insert,insert在插入时的键值对的key由我们来传参,而value用其对应类型的匿名构造来代替,所以如果key不存在,那insert就表示插入,如果key已经存在,则[ ]既可以修改,又可以查找。

在这里插入图片描述
在这里插入图片描述

8.
所以用[ ]可以直接统计出次数,将对应的arr每个元素插入到map里面,如果key存在,则[ ]内部的insert会返回已经存在的key对应的迭代器,通过此迭代器可以拿到value的引用,又因为int类型匿名构造是0,则value初始化是0,++就是1,所以countMap.[e]++就可以直接统计出水果出现的次数。

int main()
{//定义一个map统计水果出现的次数string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉" ,"草莓","草莓", "香蕉", "西瓜", };map<string, int> countMap;//for (auto& e : arr)//{//	//map<string, int>::iterator it = countMap.find(e);//	auto it = countMap.find(e);//	if (it == countMap.end())//		countMap.insert(make_pair(e, 1));//	else//		it->second++;//}for (auto& e : arr){countMap[e]++;//  (   *(   (this->insert(make_pair(k, mapped_type()))).first  )   ).second //迭代器指向的是pair类实例化的对象,我们称这个对象为键值对}for (const auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}return 0;
}

9.
注意:在元素访问时,有一个与operator[]类似的操作at()(该函数不常用)函数,都是通过
key找到与key对应的value然后返回其引用,不同的是:当key不存在时,operator[]用默认
value与key构造键值对然后插入,返回该默认value,at()函数直接抛异常

2.3 multimap的使用

1.
multimap是没有[ ]的,因为multimap支持key值进行重复,那[ ]返回哪个key的引用呢?太乱了吧,所以multimap没有重载[ ]运算符。其余接口的使用和map一样,这里不作介绍。

三、两道OJ题

1.前K个高频单词(less小于号是小的在左面升序,greater大于号是大的在左面降序)

前K个高频单词

1.
我们可以用排序的思路来解决这道题,定义string和int的键值对,然后将所有单词存到map里面,这样map里面就有单词和单词出现的次数的键值对了,并且string还是按照字典顺序排好了。然后我们将键值对利用sort来进行排序,但由于map的迭代器是双向迭代器,而sort要求支持随机访问,因为他底层是快排,那就需要随机迭代器,所以我们将map中的键值对语法糖式的尾插到vector里面,vector的迭代器是随机迭代器,可以适用于快排。

2.
比较vector中的键值对时,快排是不稳定的,当两个单词的出现次数一样时,那在快排比较的时候是有可能打乱两个单词在vector里面出现的顺序的,所以我们可以采取stable_sort进行排序,代码里面写出了错误示范,其实问题不仅仅出现在sort上面,而是出现在pair的比较规则上面去了,所以要想解决问题,还是得从排序的比较规则上面入手,我们重写仿函数,自己定义比较的规则就好了,让这个比较规则契合题目逻辑。

快排的确是不稳定的,这确实没毛病。
在这里插入图片描述
在这里插入图片描述

3.
sort排序想要正确,他的仿函数逻辑要分两种情况,一种是只有左边键值对的次数大于右边时才可以交换,另一种是关键,因为快排不是不稳定么,那我们就调整逻辑让他稳定,当次数相等时,必须保证second的相对顺序不变,不能随意交换。那就增加条件为:左边的string小于右边的string才返回true。
(这个地方你可以这么理解,因为算法库中默认的less排升序,less里面是小于号,那就是小的在左面,greater排降序,greater里面是大于号,大的在左面,这样理解的话,当次数相同时我们想让字符串小的在左面,那就应该用小于号进行比较,所以仿函数里面second比较那里用小于号

4.
这里并没有改变sort的稳定性,只是调整了比较的逻辑,如果不控制first相等时的string顺序,那快排就会随意打乱次数相等的单词,但这并不是我们想看到的,所以我们现在强行控制逻辑,不让快排打乱单词的顺序,必须按照字典顺序保证string小的单词在左面

class Solution {
public:struct compare{bool operator()(const pair<int, string>& left, const pair<int, string>& right){return left.first > right.first || (left.first==right.first && left.second < right.second);//second用小于号比较}};vector<string> topKFrequent(vector<string>& words, int k) {vector<string> ret;map<string, int> mp;for(const auto& str : words){mp[str]++;}vector<pair<int, string>> v;//用vector来排序,map是双向迭代器,不支持随机访问for(const auto& kv : mp){v.push_back(make_pair(kv.second, kv.first));}//第一个是错误写法示例,greater排降序,但pair默认的比较规则不符合题目要求stable_sort(v.begin(), v.end(), greater<pair<int ,string>>);sort(v.begin(), v.end(), compare());for(int i=0; i<k; i++){ret.push_back(v[i].second);}return ret;}
};

5.
下面采用稳定排序的方式进行排序,稳定排序不用考虑first相等时单词有可能被打乱顺序的情况,因为稳定排序不会打乱相等值的相对顺序。

6.
所以仿函数逻辑就是,只有左边的键值对的first大于右边的first(vector中键值对的first是单词出现次数)时,我们才会返回true,进行交换,其他相等或小于的情况都不允许交换,这样就可以保证大的在左面,就能完成降序的工作了。

在这里插入图片描述

class Solution {
public:struct compare{bool operator()(pair<int, string> left, pair<int, string> right){return left.first > right.first;}};vector<string> topKFrequent(vector<string>& words, int k) {vector<string> ret;map<string, int> mp;for(const auto& str : words){mp[str]++;}vector<pair<int, string>> v;//用vector来排序,map是双向迭代器,不支持随机访问for(const auto& kv : mp){v.push_back(make_pair(kv.second, kv.first));}stable_sort(v.begin(), v.end(), compare());for(int i=0; i<k; i++){ret.push_back(v[i].second);}return ret;}
};

2.两个数组的交集(排序+去重,简单的比对算法)

两个数组的交集

1.
这道题目就比较简单了,我们可以利用set先进行排序+去重,然后比较两个set里面的值,如果两个值相等时,说明这个值是两个数组的交集,两个迭代器同时往后走,去后面继续比较,如果不相等,那就让较小元素对应的迭代器往后++,因为在小元素的后面才会有可能和另一个set当前的值相等。

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int> ret;set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());auto it1 = s1.begin();auto it2 = s2.begin();while(it1 != s1.end() && it2 != s2.end()){if(*it1 < *it2){it1++;}else if(*it1 > *it2){it2++;}else{ret.push_back(*it1);it1++;it2++;}}return ret;}
};

相关文章:

【C++】map、set、multimap、multiset的介绍和使用

我讨厌世俗&#xff0c;也耐得住孤独。 文章目录一、键值对二、树形结构的关联式容器1.set1.1 set的介绍1.2 set的使用1.3 multiset的使用2.map2.1 map的介绍2.2 map的使用2.3 multimap的使用三、两道OJ题1.前K个高频单词&#xff08;less<T>小于号是小的在左面升序&…...

css学习14(多媒体查询)

目录 多媒体查询 语法 示例代码 通用媒体查询 媒体功能参考列表 多媒体查询 CSS的媒体查询是一种CSS的技术&#xff0c;它可以根据不同的设备类型、屏幕尺寸、方向、分辨率等条件来应用不同的CSS样式&#xff0c;从而为不同的设备和屏幕提供最佳的浏览体验。这样&#xff…...

【C++进阶】C++11(中)左值引用和右值引用

文章目录左值引用左值引用的概念左值引用的使用右值引用右值引用的概念右值引用的使用左右值相互引用左值引用对右值进行引用右值引用对左值进行引用右值引用使用场景和意义左值引用的优势左值引用的短板右值引用的优势完美转发模板万能引用完美转发实际运用场景左值引用 左值…...

Python中的生成器【generator】总结,看看你掌握了没?

人生苦短&#xff0c;我用python python 安装包资料:点击此处跳转文末名片获取 1.实现generator的两种方式 python中的generator保存的是算法&#xff0c; 真正需要计算出值的时候才会去往下计算出值。 它是一种惰性计算&#xff08;lazy evaluation&#xff09;。 要创建一个…...

MD5加密竟然不安全,应届生表示无法理解?

前言 近日公司的一个应届生问我&#xff0c;他做的一个毕业设计密码是MD5加密存储的&#xff0c;为什么密码我帮他调试的时候&#xff0c;我能猜出来明文是什么&#xff1f; 第六感&#xff0c;是后端研发的第六感&#xff01; 正文 示例&#xff0c;有个系统&#xff0c;前…...

【Linux】虚拟地址空间

进程地址空间一、引入二、虚拟地址与物理内存的联系三、为什么要有虚拟地址空间一、引入 对于C/C程序&#xff0c;我们眼中的内存是这样的&#xff1a; 我们利用这种对于与内存的理解看一下下面这段代码&#xff1a; 运行结果&#xff1a; 观察父子进程中 val 变量的值&…...

四平方和题解(二分习题)

四平方和 暴力做法 Y总暴力做法&#xff0c;蓝桥云里能通过所有数据 总结&#xff1a;暴力也分好坏&#xff0c;下面这份代码就是写的好的暴力 如何写好暴力:1. 按组合枚举 2. 写好循环结束条件&#xff0c;没必要循环那么多次 #include<iostream> #include<cmath>…...

一篇文章搞定js正则表达式

我们测试正则表达式是否正确的方法有很多&#xff0c;例如通过正则表达式找到拼配的字符串&#xff1a; 在vscode编辑器中点击搜索框中的第三个按钮就可以实现&#xff1a; 或者 在浏览器中的控制台也可以实现&#xff1a; 我们可以通过下面的在线网站来测试你写的正则是否正确…...

[数据结构] 用两个队列实现栈详解

文章目录 一、队列实现栈的特点分析 1、1 具体分析 1、2 整体概括 二、队列模拟实现栈代码的实现 2、1 手撕 队列 代码 queue.h queue.c 2、2 用队列模拟实现栈代码 三、总结 &#x1f64b;‍♂️ 作者&#xff1a;Ggggggtm &#x1f64b;‍♂️ &#x1f440; 专栏&#xff1…...

官宣|Apache Flink 1.17 发布公告

Apache Flink PMC&#xff08;项目管理委员&#xff09;很高兴地宣布发布 Apache Flink 1.17.0。Apache Flink 是领先的流处理标准&#xff0c;流批统一的数据处理概念在越来越多的公司中得到认可。得益于我们出色的社区和优秀的贡献者&#xff0c;Apache Flink 在 Apache 社区…...

动态内存管理+动态通讯录【C进阶】

文章目录为什么存在动态内存分配❓&#x1f449;动态内存函数&#x1f448;malloc&freecallocrealloc❌常见的动态内存错误❌练习题&#x1fae0;C/C程序的内存开辟&#x1f914;柔性数组柔性数组的特点柔性数组的优势:star:动态通讯录:star:初始化添加销毁为什么存在动态内…...

基于pytorch+Resnet101加GPT搭建AI玩王者荣耀

本源码模型主要用了SamLynnEvans Transformer 的源码的解码部分。以及pytorch自带的预训练模型"resnet101-5d3b4d8f.pth"本资源整理自网络&#xff0c;源地址&#xff1a;https://github.com/FengQuanLi/ResnetGPT注意运行本代码需要注意以下几点 注意&#xff01;&a…...

多线程控制讲解与代码实现

多线程控制 回顾一下线程的概念 线程是CPU调度的基本单位&#xff0c;进程是承担分配系统资源的基本单位。linux在设计上并没有给线程专门设计数据结构&#xff0c;而是直接复用PCB的数据结构。每个新线程&#xff08;task_struct{}中有个指针都指向虚拟内存mm_struct结构&am…...

清晰概括:进程与线程间的区别的联系

相关阅读&#xff1a; &#x1f517;通俗简介&#xff1a;操作系统之进程的管理与调度&#x1f517;如何使用 jconsole 查看Java进程中线程的详细信息&#xff1f; 目录 一、进程与线程 1、进程 2、线程 二、进程与线程之间的区别和联系 1、区别 2、联系 一、进程与线程 …...

自定义类型 (结构体)

文章目录&#x1f4ec;结构体的声明&#x1f50e;1.结构的基础知识&#x1f50e;2.结构的声明&#x1f50e;3.特殊的声明&#x1f50e;4.结构的自引用&#x1f50e;5.结构体变量的定义和初始化&#x1f50e;6.结构体内存对齐&#x1f50e;7.修改默认对齐数&#x1f50e;8.结构体…...

第14届蓝桥杯STEMA测评真题剖析-2023年3月12日Scratch编程初中级组

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第113讲。 蓝桥杯选拔赛现已更名为STEMA&#xff0c;即STEM 能力测试&#xff0c;是蓝桥杯大赛组委会与美国普林斯顿多…...

程序员接私活一定要知道的事情,我走的弯路你们都别走了

文章目录前言一、程序员私活的种类1.兼职职位众包2.自由职业者驻场3.项目整包二、这3种私活可以接1.有熟人2.七分熟的项目3.需求明确的项目三、这3种私活不要接1.主动找上门的中介单2.一味强调项目简单好做3.外行人给你拉的项目四、接单的渠道1.线下渠道2.线上渠道3.比较靠谱的…...

十二届蓝桥杯省赛c++(下)

1、 拿到题目一定要读懂题意&#xff0c;不要看到这题目就上来模拟什么闰年&#xff0c;一月的天数啥的。这个题目问你当天的时间&#xff0c;就说明年月日跟你都没关系&#xff0c;直接无视就好了。 #include <iostream> #include <cstring> #include <algori…...

数据结构与算法——堆的基本存储

目录 一、概念及其介绍 二、适用说明 三、结构图示 四、Java 实例代码 五.堆和栈的区别 一、概念及其介绍 堆(Heap)是计算机科学中一类特殊的数据结构的统称。 堆通常是一个可以被看做一棵完全二叉树的数组对象。 堆满足下列性质&#xff1a; 堆中某个节点的值总是不大…...

来了来了 !!!K8s指令、yaml部署

文章目录k8s资源清单一、k8s资源指令1、基础操作2、命令手册二、资源清单1、required2、optional3、other4、资源清单格式5、常用命令三、部署实例1、nginx3、eureka部署k8s资源清单 一、k8s资源指令 1、基础操作 #创建且运行一个pod #deployment、rs、pod被自动创建 kubect…...

spring-cloud-feign实战笔记

feign 配置 针对单个feign接口进行配置feign:client:config:# feignName 注意这里与contextId一致&#xff0c;不能写成name&#xff08;FeignClientFactoryBean#configureFeign&#xff09;# 不能写成 client-b (微服务名称)&#xff0c;否则不生效helloFeignClient: # conte…...

【Pytorch】利用PyTorch实现图像识别

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 这是目录使用torchvision库的datasets类加载常用的数据集或自定义数据集使用torchvision库进行数据增强和变换&#xff0c;自定义自己的图像分类数据集并使用torchvision库加载它们使…...

在家查找下载最新《柳叶刀》The Lancet期刊文献的方法

《柳叶刀》The Lancet简介&#xff1a; 《柳叶刀》The Lancet是全球顶尖综合性医学期刊&#xff0c;每周都会发表来自世界各地顶尖科学家的研究精粹。是由托马斯威克利&#xff08;Thomas Wakley&#xff09;创办于1823年&#xff0c;由爱思唯尔&#xff08;Elsevier&#xff…...

当下的网络安全行业前景到底怎么样?还能否入行?

前言网络安全现在是朝阳行业&#xff0c;缺口是很大。不过网络安全行业就是需要技术很多的人达不到企业要求才导致人才缺口大常听到很多人不知道学习网络安全能做什么&#xff0c;发展前景好吗&#xff1f;今天我就在这里给大家介绍一下。网络安全作为目前比较火的朝阳行业&…...

SpringCloud:SpringAMQP介绍

Spring AMQP是基于RabbitMQ封装的一套模板&#xff0c;并且还利用SpringBoot对其实现了自动装配&#xff0c;使用起来非常方便。Spring AMQP官方地址 Spring AMQP提供了三个功能&#xff1a; 自动声明队列、交换机及其绑定关系基于注解的监听器模式&#xff0c;异步接收消息封…...

第十三届蓝桥杯省赛 python B组复盘

文章目录前言主要内容&#x1f99e;试题 A&#xff1a;排列字母思路代码&#x1f99e;试题 B&#xff1a;寻找整数思路代码&#x1f99e;试题 C&#xff1a;纸张尺寸思路代码&#x1f99e;试题 D&#xff1a;数位排序思路代码&#x1f99e;试题 E&#xff1a;蜂巢思路代码&…...

SQL注入之HTTP请求头注入

Ps&#xff1a; 先做实验&#xff0c;在有操作的基础上理解原理会更清晰更深入。 一、实验 sqli-lab 1. User-Agent注入 特点&#xff1a;登陆后返回用户的 User-Agent --> 服务器端可能记录用户User-Agent 输入不合法数据报错 payload: and updatexml(1,concat("~&…...

Metasploit详细教程

第一步&#xff1a;安装和启动Metasploit 您可以从Metasploit官方网站下载适用于您操作系统的Metasploit框架。安装Metasploit框架后&#xff0c;您可以使用以下命令来启动Metasploit&#xff1a; msfconsole该命令将启动Metasploit控制台。 第二步&#xff1a;查找目标设备…...

【ChatGPT】Notion AI 从注册到体验:如何免费使用

欢迎关注【youcans的GPT学习笔记】原创作品&#xff0c;火热更新中 【ChatGPT】Notion AI 从注册到体验1. Notion AI 介绍1.1 Notion AI 简介1.2 Notion AI 的核心能力1.3 Notion AI 与 ChatGPT 的比较2. Notion AI 国内用户注册2.1 PC 端用户注册2.2 移动端用户注册3. Notion …...

每个开发人员都需要掌握的10 个基本 SQL 命令

SQL 是一种非常常见但功能强大的工具&#xff0c;它可以帮助从任何数据库中提取、转换和加载数据。数据查询的本质在于SQL。随着公司和组织发现自己处理的数据量迅速增加&#xff0c;开发人员越来越需要有效地使用数据库来处理这些数据。所以想要暗恋数据领域&#xff0c;SQL是…...

win2003做网站/网络营销策划书的范文

cURL 是一个利用URL语法规定来传输文件和数据的工具&#xff0c;支持很多协议&#xff0c;如HTTP、FTP、TELNET等&#xff0c;我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数&#xff0c;并且支持HTTPS。本文将介绍cURL的一些特性&…...

wordpress换行符/网页设计制作网站素材

今天用了一下python发送带附件的邮件&#xff0c;结果弄了半天&#xff0c;一直报这个错误&#xff1a;smtplib.SMTPDataError: (554, b’DT:SPM 126 smtp10。 import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipartsend_addr…...

武汉网站定制/百度手机助手网页版

实际开发中遇到问题&#xff0c;有一个数组&#xff0c;需要把它的key取出来并在下拉框中进行显示&#xff0c;但不知如何获取数组的 key&#xff1f; 举个例子比如 var array [{ 0: ‘a’}, { 1: ‘b’ }, { 2: ‘c’ }] 需要取出key&#xff0c;构成一个新的数组 [‘0’, ‘…...

河南郑州有疫情吗/5g站长工具seo综合查询

由于Linux系统太深奥&#xff0c;本人纯属菜鸟一般所以只要搞懂怎么配置就好了&#xff0c;目前不需要弄懂为什么要那么配置&#xff01; Linux网卡配置文件的路径&#xff1a; CentOS7: /etc/sysconfig/network-scripts/ifcfg-eno16777736 CentOS6: /etc/sysconfig/network-sc…...

网站改版seo/如何做seo整站优化

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2022年T电梯修理复训题库系T电梯修理理论题库新版习题库&#xff01;2022T电梯修理考试题库及模拟考试根据T电梯修理考前押题。T电梯修理复审题库通过安全生产模拟考试一点通随机组卷。 1、【多选题】电梯在&#xff…...

网页设计作业百度云/上海百度seo优化

DLL 有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容。DLL 是一个包含可由多个程序同时使用的代码和数据的库。下面为你介绍C/C中动态链接库的创建和调用。动态连接库的创建步骤&#xff1a;创建Dll有两种方式。一、创建Non-MFC DLL动态链接库1、打开Fi…...