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

【C++】哈希表

1. unordered系列关联式容器

在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 ,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。

最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对unordered_map和unordered_set进行介绍。(unordered_multimap和unordered_multiset 使用的不多,用法与multimap和multiset使用类似)

1.1. unordered_map

1.1.1. 使用介绍

unordered_map是存储<key, value>键值对的关联式容器,其允许通过keys快速的索引到与其对应的value。
在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。
在内部,unordered_map没有对<kye, value>按照任何特定的顺序排序, 为了能在常数范围内找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。
unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭代方面效率较低。
unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问value。
它的迭代器至少是前向迭代器。

unordered_map使用文档

1.1.2. 接口说明

  1. unordered_map的构造

函数声明

功能介绍

unordered_map

构造不同格式的unordered_map对象

  1. unordered_map的容量

函数声明

功能介绍

bool empty() const

检测unordered_map是否为空

size_t size() const

获取unordered_map的有效元素个数

  1. unordered_map的迭代器

函数声明

功能介绍

begin

返回unordered_map第一个元素的迭代器

end

返回unordered_map最后一个元素下一个位置的迭代器

cbegin

返回unordered_map第一个元素的const迭代器

cend

返回unordered_map最后一个元素下一个位置的const迭代器

  1. unordered_map的元素访问

函数声明

功能介绍

operator[]

返回与key对应的value,没有一个默认值

注意:该函数中实际调用哈希桶的插入操作,用参数key与V()构造一个默认值往底层哈希桶中插入,如果key不在哈希桶中,插入成功,返回V(),插入失败,说明key已经在哈希桶中,将key对应的value返回。

  1. unordered_map的查询

函数声明

功能介绍

iterator find(const K& key)

返回key在哈希桶中的位置

size_t count(const K& key)

返回哈希桶中关键码为key的键值对的个数

注意:unordered_map中key是不能重复的,因此count函数的返回值最大为1

  1. unordered_map的修改操作

函数声明

功能介绍

insert

向容器中插入键值对

erase

删除容器中的键值对

void clear()

清空容器中有效元素个数

void swap(unordered_map&)

交换两个容器中的元素

  1. unordered_map的桶操作

函数声明

功能介绍

size_t bucket_count()const

返回哈希桶中桶的总个数

size_t bucket_size(size_t n)const

返回n号桶中有效元素的总个数

size_t bucket(const K& key)

返回元素key所在的桶号

1.2. unordered_set

其功能与接口和unordered_map类似,这里就不再详细列举出其使用方法和接口。

详细请参考unordered_set使用手册

1.3. unordered系列容器与map和set的区别

unordered系列遍历不按key排序
unordered系列的迭代器全部是单向迭代器
unordered系列综合效率略胜map和set

map和set对key的要求:需要key能够支持比较大小,如果不能比较,必须要显式的传入比较仿函数。

unordered_map、unordered_set对key的要求:需要key能够支持取模或者转化成取模的无符号整数;需要key能够比较是否相等,或者传入仿函数。

2. 哈希表

unordered_map和unordered_set的增删查改的效率都为O(1),是非常快的,是因为它的底层结构使用了哈希表。

2.1. 哈希

理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素如果构造一种存储结构,通过某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素

插入元素

据待插入元素的关键码,以此函数计算出该元素的存储位置并按此位置进行存放

搜索元素对元素的关键码进行同样的计算,把求得的函数值当做元素的存储位置,在结构中按此位置取元素比较,若关键码相等,则搜索成功该方式即为哈希(散列)方法,哈希方法中使用的转换函数称为哈希(散列)函数,构造出来的结构称为哈希表(Hash Table)(或者称散列表)

例如:数据集合{1,7,6,4,5,9};哈希函数设置为:hash(key) = key % capacity; capacity为存储元素底层空间总的大小

2.2. 哈希冲突

例如:我们使用哈希的方法向顺序表中插入整数,顺序表的容量为10,先插入15,那么插入到数组下标为5的位置,如果再插入25,怎么办?

类似上面这种情况,将不同的元素通过哈希函数映射到了哈希表的相同位置,就是哈希冲突。

2.3. 哈希函数

引起哈希冲突的一个原因可能是:哈希函数设计不够合理哈希函数设计原则

哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值域必须在0到m-1之间
哈希函数计算出来的地址能均匀分布在整个空间中
哈希函数应该比较简单

常用哈希函数1. 直接定制法取关键字的某个线性函数为散列地址:**Hash(Key)= A*Key + B** 优点:简单、均匀 缺点:需要事先知道关键字的分布情况 使用场景:适合查找比较小且连续的情况 面试题:字符串中第一个只出现一次字符

2.除留余数法散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函数:Hash(key) = key% p(p<=m),将关键码转换成哈希地址。

2.4. 哈希冲突解决

解决哈希冲突两种常见的方法是:闭散列开散列

2.4.1 闭散列

闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去。那如何寻找下一个空位置呢?

  1. 线性探测

比如上面举的例子,现在需要插入元素25,先通过哈希函数计算哈希地址,hashAddr为5,因此25理论上应该插在该位置,但是该位置已经放了值为15的元素,即发生哈希冲突。线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。

  1. 二次探测

发生哈希冲突后寻找下一位空位置的方法为:Hi = (H0+i^2)%m (i=1,2,3...),H0是通过散列函数Hash(x)对元素的关键码 key 进行计算得到的位置,m是表的大小。

线性探测优点:简单。

线性探测缺点:一旦发生哈希冲突,所有的冲突连在一起,容易产生数据“堆积”,即:不同关键码占据了可利用的空位置,使得寻找某关键码的位置需要许多次比较,导致搜索效率降低。

二次探测优点:缓解线性探测的数据堆积问题。

二次探测缺点:空间利用率较低。

还有一个有效解决哈希冲突的方法是扩容,这样能将部分数据的映射位置分开。

注意:

采用闭散列处理哈希冲突时,不能随便物理删除哈希表中已有的元素直接删除元素会影响其他元素的搜索 。

实际的处理方法是,给每一个位置做一个标记位,通过改变标记位来控制删除。(例如:empty为空,exist为存在,delete为删除)

2.4.2 开散列

开散列概念

开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。

这样就能很好的解决哈希冲突的问题,实际哈希表在实现时也是使用的这种方法。

3. 位图

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】

将所有数据存放在位图中,数据是否在给定的位图中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。节省了大量空间。

3.1. 概念

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

3.2. 位图的实现

#pragma once
#include <vector>namespace bit
{template<size_t N>class bitset{public:bitset(){_bits.resize(N / 8 + 1, 0); //为了避免存入数据的个数不是8的整数倍,所以多开一开字节}void set(size_t x){size_t i = x / 8; // 找到存入的值在哪个字节size_t j = x % 8; // 找到在该字节中的具体位置_bits[i] |= (1 << j); // 将该位置置为1}void reset(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] &= (~(1 << j));}bool test(size_t x){size_t i = x / 8;size_t j = x % 8;return _bits[i] & (1 << j);}private:std::vector<char> _bits; // 每个字段8个比特位//std::vector<int> _bits;};

3.3. 位图的应用

  1. 快速查找某个数据是否在一个集合中

  1. 排序

  1. 求两个集合的交集、并集等

  1. 操作系统中磁盘块标记

4. 布隆过滤器

如果遇到数据量非常大的问题,虽然有些可以使用位图解决,但是位图的使用非常局限,即位图中只能存整数,那么如果遇到字符串、自定义类型怎么办?

4.1. 布隆过滤器概念

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间。

4.2. 布隆过滤器的实现

由于布隆过滤器的底层也是由位图去实现的,那么就出现了一个问题,位图中的映射关系是直接映射,那么如果使用哈希函数将其他类型转化成整数就必然存在哈希冲突问题。

所以为了解决位图中的哈希冲突,布隆过滤器中使用了多个哈希函数,将转化的整数形成多个映射,存放在位图的不同位置。(当然这种方式不能完全解决哈希冲突)

#pragma once#include <bitset>
#include <string>
#include <time.h>struct BKDRHash
{size_t operator()(const string& s){// BKDRsize_t value = 0;for (auto ch : s){value *= 31;value += ch;}return value;}
};struct APHash
{size_t operator()(const string& s){size_t hash = 0;for (long i = 0; i < s.size(); i++){if ((i & 1) == 0){hash ^= ((hash << 7) ^ s[i] ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ s[i] ^ (hash >> 5)));}}return hash;}
};struct DJBHash
{size_t operator()(const string& s){size_t hash = 5381;for (auto ch : s){hash += (hash << 5) + ch;}return hash;}
};template<size_t N,
size_t X = 8,
class K = string,
class HashFunc1 = BKDRHash,
class HashFunc2 = APHash,
class HashFunc3 = DJBHash>
class BloomFilter
{
public:void Set(const K& key){size_t len = X*N;size_t index1 = HashFunc1()(key) % len;size_t index2 = HashFunc2()(key) % len;size_t index3 = HashFunc3()(key) % len;/*    cout << index1 << endl;cout << index2 << endl;cout << index3 << endl<<endl;*/_bs.set(index1);_bs.set(index2);_bs.set(index3);}bool Test(const K& key){size_t len = X*N;size_t index1 = HashFunc1()(key) % len;if (_bs.test(index1) == false)return false;size_t index2 = HashFunc2()(key) % len;if (_bs.test(index2) == false)return false;size_t index3 = HashFunc3()(key) % len;if (_bs.test(index3) == false)return false;return true;  // 存在误判的}// 不支持删除,删除可能会影响其他值。void Reset(const K& key);
private:bitset<X*N> _bs;
};

注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。

为了降低布隆过滤器的误判问题,可以适当增大位图的大小。

4.3. 布隆过滤器删除

布隆过滤器不能直接支持删除工作,因为在删除一个元素时,如果该位置也可能映射有其他元素,可能就会影响其他元素。

一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作

缺陷:

  1. 无法确认元素是否真正在布隆过滤器中

  1. 存在计数回绕

4.3. 布隆过滤器优点

  1. 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关

  1. 哈希函数相互之间没有关系,方便硬件并行运算

  1. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势

  1. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势

  1. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能

  1. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算

4.4. 布隆过滤器缺陷

  1. 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据)

  1. 不能获取元素本身

  1. 一般情况下不能从布隆过滤器中删除元素

  1. 如果采用计数方式删除,可能会存在计数回绕问题

布隆过滤器使用场景:数据量大,节省空间,允许误判,这样的场景,就可以使用布隆过滤器。

如:注册时,输入昵称时,将数据库中的昵称放入布隆过滤器中检查是否存在。(昵称不存在时不会发生误判,如果存在可能会发生误判,但是不会影响数据库中的数据(即误判了本来不存在的昵称为存在))

5. 海量数据面试题

5.1. 哈希切割

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?

哈希切分:

(1)依次读取IP,i = BKDRHash(ip)%200(n),i是多少ip就进入对应编号的小文件中,相同的ip就一定进入了同一个小文件,然后使用map统计一个小文件的ip的次数,就是这个ip准确的次数。

(2)使用priority_queue,将map中的每个ip插入小堆中,即可统计出来。

5.2. 位图应用

1.给定100亿个整数,设计算法找到只出现一次的整数?

使用两个位图,将两个位图相同的位置用作一个整数的计数(00:未出现,01:出现一次,10:出现两次及以上),这样只找01位置的数即可。

代码:

template<size_t N>
class TwoBitSet
{
public:void Set(size_t x){if (!_bs1.test(x) && !_bs2.test(x)) // 00 -> 01{_bs2.set(x);}else if (!_bs1.test(x) && _bs2.test(x)) // 01 -> 10{_bs1.set(x);_bs2.reset(x);}// 10 表示已经出现2次或以上,不用处理}void PrintOnceNum(){for (size_t i = 0; i < N; ++i){if (!_bs1.test(i) && _bs2.test(i)) // 01{cout << i << endl;}}}
private:bit::bitset<N> _bs1;bit::bitset<N> _bs2;
};

2.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

把一个文件中的整数set到位图bs1中,另一个文件set到位图bs2中。

  1. 遍历bs1中的值,然后看这个值在不在bs2中。

  1. 将两个位图相与,得到的结果位图中,为1的位置就是交集。

3.位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数

同第一题一样,使用两个位图,00:未出现,01:出现1次,10:出现2次,11:出现3次及以上。

5.3. 布隆过滤器

1.给两个文件,分别有100亿个query(查询),我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。

近似算法:将一个文件放入布隆过滤器,遍历另一个文件,看它在布隆过滤器中有没有,如果存在就是交集。(存在误判,会导致不是交集的query也被找出来)

精确算法:哈希切分:分别读取两个的query,使用哈希算法(如:i = BKDRHash(query)%200),得到的结果分别放入Ai、Bi号小文件,这样相同的文件就会被放进相同编号(i)的文件中,然后相同的编号文件进行比较即可。(如果单个小文件太大,超过内存,可以考虑换个哈希算法,再切分一次)

相关文章:

【C++】哈希表

1. unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到 &#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好的查询是&#xff0c;进行…...

深度学习入门(六十七)循环神经网络——注意力机制

深度学习入门&#xff08;六十七&#xff09;循环神经网络——注意力机制前言循环神经网络——注意力机制课件心理学注意力机制注意力机制是显式地考虑随意线索非参注意力池化层Nadaraya-Watson 核回归&#xff1a;总结教材&#xff08;注意力提示&#xff09;1 生物学中的注意…...

阿里云云通信风控系统的架构与实践

作者&#xff1a;铭杰 阿里云云通信创立于 2017 年&#xff0c;历经 5 年发展已经孵化出智能消息、智能语音、隐私号、号码百科等多个热门产品。目前&#xff0c;已成为了国内云通信市场的领头羊&#xff0c;在国际市场上服务范围也覆盖了 200 多个国家。随着业务的不断壮大&am…...

【性能测试】loadrunner(一)知识准备

【性能测试】loadrunner&#xff08;一&#xff09;知识准备 目录&#xff1a;导读 1.0. 前言 1.1 性能测试术语介绍 1.2 性能测试分类 1.3 HTTP我们需要知道的 1.4 Loadrunner 12.55安装 1.0. 前言 ​ 在性能测试中&#xff0c;牵扯到了许多比较杂的知识点&#xff0c;…...

【Vue3源码】第五章 ref的原理 实现ref

【Vue3源码】第五章 ref的原理 实现ref 上一章节我们实现了reactive 和 readonly 嵌套对象转换功能&#xff0c;以及shallowReadonly 和isProxy几个简单的API。 这一章我们开始实现 ref 及其它配套的isRef、unRef 和 proxyRefs 1、实现ref 接受一个内部值&#xff0c;返回一…...

[Flink]部署模式(看pdf上的放上面)

运行一个wordcountval dataStream: DataStream[String] environment.socketTextStream("hadoop1", 7777) //流式数据不能进行groupBy,流式数据要来一条处理一次.0表示第一个元素,1表示第二个元素 //keyBy(0)根据第一个元素进行分组 val out: DataStream[(String, In…...

Linux 查看 CPU 信息,机器型号,内存等信息

平时用的可能少&#xff0c;但需要记住&#xff0c;使用的命令&#xff0c;转载https://my.oschina.net/hunterli/blog/140783&#xff0c;以记录学习 系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/…...

三维量子力学 量子力学(3)

动量ppp有三个分量&#xff0c;为pxp_xpx​等。它们分别满足与位置坐标的对易关系&#xff0c;比如px−iℏ∂∂xp_x-i\hbar\frac{\partial }{\partial x}px​−iℏ∂x∂​。可以用位置坐标梯度算符表示即p−iℏ∇\bm{p}-i\hbar\nablap−iℏ∇。位置矢量用r\bm{r}r表示。 在d3r…...

Blazor入门100天 : 身份验证和授权 (6) - 使用 FreeSql orm 管理ids数据

目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 本节源码 https://github.com/…...

Java文件IO操作:File类的相关内容

Java文件IO操作一、File类1.相对路径和绝对路径2.路径分隔符&#xff08;同一路径下、多个路径下&#xff09;3.实例化4.常见方法一、File类 File类继承自Object类&#xff0c;实现了Serializable接口和Comparable接口&#xff1b; File类属于java.io包&#xff1b; File类是文…...

竣达技术 | 巡检触摸屏配合电池柜,电池安全放首位!

机房蓄电池常见的故障 1.机房电池着火和爆炸 目前在数据机房蓄电池爆炸着火事故频发&#xff0c;导致业主损失严重。一般机房电池是由于其中一节电池裂化后未妥善管理&#xff0c;电池急剧恶化导致爆炸着火。由于电池是串联及并联在使用&#xff0c;只要一节着火燃烧整片瞬间…...

什么是自动化运维?为什么选择Python做自动化运维?

“Python自动化运维”这个词&#xff0c;想必大家都听说过&#xff0c;但是很多人对它并不了解&#xff0c;也不知道是做什么的&#xff0c;那么你对Python自动化运维了解多少呢?跟着蛋糕往下看。 什么是Python自动化运维? 随着技术的进步、业务需求的快速增长&#xff0c;…...

【经验】移植环境requirement时报错

问题描述 在使用pip freeze > ./requirements.txt和pip install -r requirement.txt &#xff08;requirements.txt文件用来记录当前程序的所有依赖包及其精确版本号&#xff09;从一台电脑移植到另一台电脑的 conda 环境时&#xff0c;出现了一堆类似的报错&#xff1a; E…...

计算机专业要考什么证书?

大家好&#xff0c;我是良许。 从去年 12 月开始&#xff0c;我已经在视频号、抖音等主流视频平台上连续更新视频到现在&#xff0c;并得到了不错的评价。 视频 100% 原创录制&#xff0c;绝非垃圾搬运号&#xff0c;每个视频都花了很多时间精力用心制作&#xff0c;欢迎大家…...

一个列表引发的思考(简单版)

最近老板让我按照设计图写一个页面&#xff0c;不嫌丢人的说这是我第一次写页面&#xff0c;哈哈哈。 然后设计图里有一个这样的需求&#xff0c;感觉挺有意思的。 为什么感觉有意思呢&#xff0c;因为这个列表它前面是图片&#xff0c;然后单行和双行的不一样。&#xff08;请…...

Protobuf 学习简记(三)Unity C#中的序列化与反序列化

Protobuf 学习简记&#xff08;三&#xff09;Unity C#中的序列化与反序列化对文本的序列化与反序列化内存二进制流的序列化与反序列化方法一方法二参考链接对文本的序列化与反序列化 private void Text() {TestMsg1 myTestMsg new TestMsg1();myTestMsg.TestInt32 1;myTest…...

Flask入门(10):Flask使用SQLAlchemy

目录11.SQLAlchemy11.1 简介11.2 安装11.3 基本使用11.4 连接11.5 数据类型11.6 执行原生sql11.7 插入数据11. 8 删改操作11.9 查询11.SQLAlchemy 11.1 简介 SQLAlchemy的是Python的SQL工具包和对象关系映射&#xff0c;给应用程序开发者提供SQL的强大功能和灵活性。它提供了…...

我的 System Verilog 学习记录(4)

引言 本文简单介绍 System Verilog 语言的 数据类型。 前文链接&#xff1a; 我的 System Verilog 学习记录&#xff08;1&#xff09; 我的 System Verilog 学习记录&#xff08;2&#xff09; 我的 System Verilog 学习记录&#xff08;3&#xff09; 数据类型简介 Sys…...

Git : 本地分支与远程分支的映射关系

概述 本文介绍 git 环境中本地分支与远程分支的映射关系的查看和调整。 1、查看本地分支与远程分支的映射关系 执行如下命令&#xff1a; git branch -vv注意就是两个 v &#xff0c;没有写错。 可以获得分支映射结果&#xff1a; dev fa***** [github/dev] update * main…...

运维必看|跨国公司几千员工稳定访问Office365,怎么实现?

【客户背景】本次分享的客户是全球传感器领域的领导者&#xff0c;其核心产品为电流和电压传感器&#xff0c;被广泛应用于驱动和焊接、可再利用能源以及电源、牵引、高精度、传统和新能源汽车等领域。 作为一家中等规模的全球化公司&#xff0c;该公司在北京、日本、西欧、东欧…...

Python GDAL读取栅格数据并基于质量评估波段QA对指定数据加以筛选掩膜

本文介绍基于Python语言中gdal模块&#xff0c;对遥感影像数据进行栅格读取与计算&#xff0c;同时基于QA波段对像元加以筛选、掩膜的操作。本文所要实现的需求具体为&#xff1a;现有自行计算的全球叶面积指数&#xff08;LAI&#xff09;.tif格式栅格产品&#xff08;下称“自…...

Vue3:有关v-model的用法

目录 前言&#xff1a; 回忆基本的原生用法&#xff1a; 原生input的封装&#xff1a; 自定义v-model参数&#xff1a; 对el-input的二次封装&#xff1a; 多个v-model进行绑定: v-model修饰符&#xff1a; v-model自定义参数与自定义修饰符的结合&#xff1a; 前言&am…...

CF1692C Where‘s the Bishop? 题解

CF1692C Wheres the Bishop? 题解题目链接字面描述题面翻译题目描述题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示代码实现题目 链接 https://www.luogu.com.cn/problem/CF1692C 字面描述 题面翻译 题目描述 有一个888\times888的棋盘&#xff0c;列编号从…...

Jenkins集成Allure报告

Jenkins集成Allure报告 紧接上文&#xff1a;Jenkins部署及持续集成——傻瓜式教程 使用Allure报告 1、在插件库下载Allure插件Allure Jenkins Plugin 2、在构建后操作中加入allure执行的报告目录&#xff08;相对于项目的路径&#xff09; 3、run.py代码改成如下 import p…...

【数据结构】AVL树

AVL树一、AVL树的概念二、AVL的接口2.1 插入2.2 旋转2.2.1 左单旋2.2.2 右单旋2.2.3 左右双旋2.2.4 右左双旋三、验证四、源码一、AVL树的概念 当我们用普通的搜索树插入数据的时候&#xff0c;如果插入的数据是有序的&#xff0c;那么就退化成了一个链表&#xff0c;搜索效率…...

这一次我不再低调,老板法拉利的车牌有我的汗水

起源: 5Why分析法最初是由丰田佐吉提出的,后来,丰田汽车公司在发展完善其制造方法学的过程中持续采用该方法。5Why分析法作为丰田生产系统的入门课程之一,是问题求解的关键培训课程。丰田生产系统的设计师大野耐一曾将5Why分析法描述为:“丰田科学方法的基础,重复五次,问…...

通过连接另一个数组的子数组得到一个数组

给你一个长度为 n 的二维整数数组 groups &#xff0c;同时给你一个整数数组 nums 。 你是否可以从 nums 中选出 n 个 不相交 的子数组&#xff0c;使得第 i 个子数组与 groups[i] &#xff08;下标从 0 开始&#xff09;完全相同&#xff0c;且如果 i > 0 &#xff0c;那么…...

公派访问学者的申请条件

知识人网海外访问学者申请老师为大家分享公派访问学者申请的基本条件以及哪些人员的申请是暂不受理的&#xff0c;供大家参考&#xff1a;一、 申请人基本条件&#xff1a;1.热爱社会主义祖国&#xff0c;具有良好的思想品德和政治素质&#xff0c;无违法违纪记录。2.具有良好专…...

多点电容触摸屏实验

目录 一、简介 二、硬件原理 ​编辑1、CT_INT 2、I2C2_SCL和I2C2_SDA 3、RESET复位引脚 三、FT54x6/FT52x6电容触摸芯片 四、代码编写 1、编写ft5426.h 2、编写ft5426.c 3、main函数 一、简介 电容屏只需要手指轻触即可&#xff0c;而电阻屏是需要手指给予一定的压力才…...

【算法与数据结构(C语言)】栈和队列

文章目录 目录 前言 一、栈 1.栈的概念及结构 2.栈的实现 入栈 出栈 获取栈顶元素 获取栈中有效元素个数 检测栈是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果不为空返回0 销毁栈 二、队列 1.队列的概念及结构 2.队列的实现 初始化队列 队尾入队列 队头出队列 获…...