第十二章 哈希表与字符串哈希

news2025/4/15 10:13:59

第十二章 哈希表与字符串哈希

  • 一、哈希表
    • 1、什么是哈希表
    • 2、算法逻辑
      • (1)哈希函数
      • (2)冲突解决
    • 3、算法模板
  • 二、字符串哈希
    • 1、算法逻辑
    • 2、算法用途
    • 3、算法模板

一、哈希表

1、什么是哈希表

在之前的文章中,我们学习过离散化的算法,但是我们之前学过的离散化算法需要先去排序,所以效率较低。但是今天我们所学的哈希表同样是为了解决离散化的问题,但是其时间复杂度只有O(1)依旧是空间换时间。

2、算法逻辑

(1)哈希函数

我们假设存在一个哈希函数(hash)。这个函数的作用就是将一个大范围的数字映射到一个小范围的数字中。这个哈希函数仅仅是听起来很高尚,其实就是取模运算。我们将一系列的数字和100取模,那么最终得到的映射值就都属于0到99的。所以哈希函数就是取模。但是这里有一个问题,101%100=1,1001%100=1。这两个数字映射到了同一个映射值,发生了冲突。那么我们如何解决这个冲突呢?

这个哈希函数所取模的数字,最好是质数,这样

(2)冲突解决

在这里插入图片描述
如上图所示,我们创建一个数组,这个数组存储不同的映射值,然后每个映射值都连接了一个链表,这个链表存储的都是具有相同映射值的值,例子如图中所示。这样的话,我们可以先去寻找映射后的值,找到对应的链表,再去遍历链表,得到对应的原值。

3、算法模板

在这里插入图片描述

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+3;
int h[N],e[N],ne[N],idx;

void insert(int x)
{
    int p=(x%N+N)%N;
    e[idx]=x;
    ne[idx]=h[p];
    h[p]=idx++;
}

bool quary(int x)
{
    int p=(x%N+N)%N;
    for(int i=h[p];i!=-1;i=ne[i])
    {
        if(e[i]==x)
        {
            return true;
        }
    }
    return false;
    
}

int main()
{
    memset(h,-1,sizeof(h));
    int n;
    cin>>n;
    while(n--)
    {
        string op;int x;
        cin>>op>>x;
        if(op=="I")
        {
            insert(x);
        }
        else
        {
            if(quary(x))puts("Yes");
            else puts("No");
        }
    }
    return 0;
}

二、字符串哈希

1、算法逻辑

在这里插入图片描述
转化成数字后,该数字可能过大,因此我们需要再对这些数字进行取模离散化。
在这里插入图片描述

我们通过转化,将不同的字符串转化成了一串数字,但是必定存在一种情况,即两个字符串不同,但是最终得到的结果是相同的,即发生了冲突。那么为了解决这个问题,众多人总结出了一种经验,当p取131,m取264 的时候,百分之99的概率不会重复。

2、算法用途

当我们知道各种前缀对应的数字后,我们可以迅速得到任意一段的子串对应的数字,即迅速得到一截子串。
在这里插入图片描述
想要得到BC这段子串,我们可以让AB段和BC段通过某种运算得到。
那么如何运算呢?
在这里插入图片描述
示意图如下图所示,但实际上a并不是和a对齐的,而是a和x对齐的。
在这里插入图片描述
此时就发生了错误,因此我们再计算子串的时候,要做的第一件事就是位数对齐

3、算法模板

在这里插入图片描述

#include<iostream>
using namespace std;
const int N=1e5+10;
typedef unsigned long long ull;
ull h[N],p[N];
char str[N];

ull get_hash(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];//位数对齐
}

int main()
{
    int n,m,px=131;
    p[0]=1;
    scanf("%d%d%s",&n,&m,str+1);
    for(int i=1;i<=n;i++)
    {
        p[i]=p[i-1]*px;
        h[i]=h[i-1]*px+str[i];//利用了前缀和的思路
    }
    while(m--)
    {
        int l1,r1,l2,r2;
        scanf("%d %d %d %d",&l1,&r1,&l2,&r2);
        if(get_hash(l1,r1)==get_hash(l2,r2))puts("Yes");
        else puts("No");
    }
    return 0;
}

我们这里利用unsigned long long去存储的话,我们会发现,当数据溢出的时候会发生数据截断。此时,就相当于取模了。

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

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

相关文章

Spring-aop技术

前言 spring-aop技术是对oop(面向对象)的一个补充&#xff0c;其底层其实就是使用aspect动态代理进行实现的&#xff0c;本篇文章将大概讨论下aop的核心实现流程 相关的核心概念 刚开始&#xff0c;先介绍下aop中比较核心的一些对象和概念&#xff0c;只要理解了这些&#xff…

【通信】粒子群算法5G物联网云网络优化【含Matlab源码 2160期】

⛄一、简介 1 引言 5G技术被大众所熟知之后&#xff0c;边缘计算也成了各行业关注的重点。最初的边缘计算概念是在2014年提出&#xff0c;到了2016年就拓展到了接入边缘&#xff0c;目前基本被定义为靠近用户边缘的、包含多种技术的接入网络&#xff0c;能够提供比较稳定的IT业…

精华推荐 | 深入浅出学习透析Nginx服务器的基本原理和配置指南「Keepalive性能优化实战篇」

Linux系统&#xff1a;Centos 7 x64Nginx版本&#xff1a;1.11.5 Nginx 是一款面向性能设计的 HTTP 服务器&#xff0c;能反向代理 HTTP&#xff0c;HTTPS 和邮件相关(SMTP&#xff0c;POP3&#xff0c;IMAP)的协议链接。并且提供了负载均衡以及 HTTP 缓存。它的设计充分使用异…

拼搏一周!刷了1000道Java高频面试题喜提阿里offer,定级P7

今年较往年相比面试要难的多&#xff0c;大环境也是对于程序员的要求越来越高&#xff0c;环境是我们无法改变的&#xff0c;我们能改变的只有自己&#xff0c;月初我一好友&#xff0c;努力拼搏一周&#xff0c;刷完了这份阿里P8大牛整理的这1000道Java高频面试题笔记&#xf…

GitHub配置SSH Keys步骤

Git配置SSH Keys步骤 许多 Git 服务器都使用 SSH 公钥进行认证。 为了向 Git 服务器提供 SSH 公钥&#xff0c;如果某系统用户尚未拥有密钥&#xff0c;必须事先为其生成一份。 生成步骤如下&#xff1a; 1. 设置用户名和邮箱 在git命令行中对git进行全局设置 git config --…

八、CANdelaStudio入门-Session

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的Session概念,欢迎各位朋友订阅、评论,…

微信小程序:用户基本信息的采集

写作背景 在开发商城小程序时需要显示用户头像、昵称、手机号等信息以便后续业务的实现&#xff0c;因此需要通过微信小程序的API采集用户数据&#xff0c;由此进行总结。 在微信小程序中获取用户信息可以通过这几种方式获取&#xff0c;getUserInfo、getUserProfile、open-da…

基于多目标遗传算法的IEEE14节点系统分布式电源选址定容matlab程序

基于多目标遗传算法的IEEE14节点系统分布式电源选址定容matlab程序 摘 要: 为更好地解决分布式电源选址定容问题&#xff0c;提出一种改进的多目标遗传算法。之后&#xff0c;考虑投资成本、网损以及电压稳定性三因素建立了一个三目标的数学模型&#xff0c;并采用上述多目标遗…

javaSE -运算符,注释,关键字(复习)

一、运算符 1.1、算术运算符 基本四则运算符 - * / %规则比较简单, 值得注意的是除法和取模 1.1.1、/ 除法 int / int 结果还是 int, 需要使用 double 来计算 public static void main(String[] args) {int a 1;int b 2;System.out.println(a / b);}要得到小数那就要使…

python>>numpy包

章节内容 什么是NumPy模块和NumPy数组 创建数组 基本数据类型 数据可视化 索引和切片 副本和视图 目录 什么是NumPy模块和NumPy数组&#xff1f; 创建数组 基本数据类型 数据可视化 索引和切片 副本和视图 什么是NumPy模块和NumPy数组&#xff1f; NumPy数组 python对象 …

pyhon项目中,使用pip安装第三方插件之后,明明使用pip list可以查到,但是在项目中import时仍然找不到怎么办?

认识pip&#xff1a;python中的pip是用来安装python第三方库的工具&#xff0c;是安装python的时候自带的。 1.安装方式&#xff1a;pip install 第三方库名&#xff0c;比如&#xff1a;pip install selenium 2.查看已安装的所有第三方库&#xff1a;pip list 或 pip3 list &…

Spring Cloud OpenFeign - - - > 日志级别配置

项目源码地址&#xff1a;https://download.csdn.net/download/weixin_42950079/87168704 OpenFeign 有 4 种日志级别&#xff1a; NONE: 不记录任何日志&#xff0c;是OpenFeign默认日志级别&#xff08;性能最佳&#xff0c;适用于生产环境&#xff09;。BASIC: 仅记录请求方…

五魔方、二阶五魔方

五魔方 五魔方是正十二面体魔方&#xff0c;其实和三阶魔方很像&#xff0c;用层先法就能复原&#xff0c;而且公式一模一样。 十二个面分为6个浅色面和6个深色面&#xff0c;所以浅色和深色各有一个中心面。 先复原浅色中心面这一层&#xff1a; 再复原浅色面的5个棱块&…

【GlobalMapper精品教程】030:栅格重采样案例教程(航测DSM)

本文讲解Globalmapper栅格重采样操作方法。数据为配套实验数据包中的data030.rar,航测内业生成的DSM,分辨率为0.04米,现在需要将其重采样为0.05米。 文章目录 一、重采样简介二、重采样操作一、重采样简介 栅格/影像数据进行配准或纠正、投影等几何变换后,像元中心位置通常…

超级记忆节目

一 问题描述 杰克逊被邀请参加电视节目“超强记忆”&#xff0c;参与者会玩一个记忆游戏。主持人先告诉参与者一个数字序列 {A1 , A2 , …, An }&#xff0c;然后对该序列执行一系列操作或查询&#xff1a; ① ADD x y D &#xff0c;表示对子序列 {Ax , …, Ay } 的每个数字…

Qt | Qt For Android、Qt5.14.2安卓开发环境搭建详细步骤

Qt | Qt For Android、Qt5.14.2安卓开发环境搭建详细步骤 目录Qt | Qt For Android、Qt5.14.2安卓开发环境搭建详细步骤1、简介2、软件下载1、Java SDK2、Android SDK3、Android NDK3、软件部署4、测试1、简介 搭建Qt For Android开发环境需要安装的软件有&#xff1a; JAVA …

第十四届蓝桥杯模拟赛(第二期)

写在前面 包含本次模拟赛的10道题题解能过样例&#xff0c;应该可以AC若有错误&#xff0c;欢迎评论区指出有疑问可私信我哈&#x1faf0;&#x1f3fb;从2023开始暴力枚举每一个数&#xff0c;直到找到正确答案 start 2022def check(num) :t str(bin(num))if t[-6:] 0000…

核函数简介

文章目录基本概念概念1概念2:Kernel Func总结内积矩阵&#xff08;Gram/Kernel Matrix&#xff09;一些思考什么是有限正半定常用的Kernel FunctionsLinear KernelPolynomial KernelRBF(Gaussian) Kernel基本概念 概念1 高维空间存在可分的情况。 我们可以找一个映射函数送过…

【C++】vector的模拟实现

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;前言&…

程序员5分钟,带你看完24岁60W年薪架构师的简历,上面竟然写着精通JVM

前言 近期&#xff0c;看了一份24岁60W年薪架构师简历&#xff0c;上面写着他的求职意向所掌握的技能....... 所掌握的技能大部分写的都是精通&#xff01;我不禁想问&#xff0c;大佬都这么强吗&#xff1f;你敢在简历上把所有的技能都写精通吗&#xff1f; 简历 下面来带…