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

哈希——字符串哈希

回顾/本期梗概

        上期我们学习了图论基础(空降链接),本期我们将学习哈希中的字符串哈希。


1、什么是哈希

        哈希算法是:通过哈希函数讲字符串、较大的数等转换为能够用变量表示的或者是直接能作为数组下标的数,通过哈希算法转换到的值,称之为哈希值。哈希值可以实现快速查找和匹配。

        比如:用数组下标计数法,统计一个字符串中,每种字母出现的次数就是一个简单的哈希,将,每个字母都映射为了对应的ascii码。


2、如何构造哈希

        原理:将字符串中的每一个字母都看作是一个数字(例:从a-z,视为1-26);将字符串视为是一个b进制的数。(注意,不能映射为0,因为如果a为0,那么a、aa、aaa的值将都视为0)

        比 如 : 可 将 字 符 串 s =  " a b c d "  视 为 2 6 进 制 的 整 数 , 则 可 以 计 算 出 :hash(s)=1*26^{3}+5*26^{2}+3*26^{1}+4*26^{0}。如果字符串很长。h(s)很容易超出long long 的范畴,为防止溢出,我们取一个固定的值 h 用hash(s)%h,使得结果在long long 范围内。

        选取两个合适的互质常熟b和h(b<h)其中h要尽可能的大一点,为了降低冲突(不同字符串计算到一个哈希值)的概率。

        一般来说:b取131或13331,h取2^{64},最终产生的哈希值的冲突的概率极低。

        假设字符串C=c1c2c3...cm,定义哈希值;

        H(C)=(c_{1}*b^{m-1}+c_{2}*b^{m-2}+...+c_{a}*b^{0})mod h


3、滚动哈希优化

        如果针对一个很长的字符串,判断其中两个长度为 len 子串是否相同如果采用O(len)的时间复杂度计算出对应的子串 hash ,那和直接取出子串比较的时间复杂度并无差异,因此我们需要使用滚动哈希优化的技巧,可以在O(1)的时间复杂度下取出子串的 hash

        (1)滚动计算到前缀哈希h(k)

        设:h(k)的字符串 C 前 k 个字符构成的子串的哈希值,(先不考虑取模);

        h(k+1)=h(k)*b+c_{k+1};

        类比10进制理解该公式,比如10进制的12345,取出前3个数是123,如果要取出前4个数,可以使用:123*10(进制)+4(C_{k+1})=1234的方法取出。

        (2)利用前缀哈希H(k)计算区间哈希值

        设:

        H(R)=c_{1}*b^{R-1}+...+c_{L-1}*b^{R-L-1}+b^{r-l-+1}

        H(L-1)=c_{1}*b^{l-2}+...+c_{L-1}*b^0

        H(L,R)=H(R)-H(L-1)*b^{R-L+1}

        因此,求L~R之间的哈希值:H(R)-H(L-1)*b^{r-l+1}

        由上述公式可知,只需要预处理出b^m,就可以在O(1)的时间内求得任意子串的哈希值

        (3)时间复杂度

        综上,如果在一个长度为 的字符串中,任意取长度为 的子串进行匹配,时间复杂度为O(n+m)


!!!

​​​​​​​!!!

​​​​​​​制​​​​​​​!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Postman 发送 JSON 格式数据
  • 【速成Redis】04 Redis 概念扫盲:事务、持久化、主从复制、哨兵模式
  • Kubernetes 深入浅出系列 | 容器剖析之容器基本实现原理
  • 力扣每日一题 字符串中最多数目的子序列 贪心 字符串 前缀和
  • Leetcode 1039. 多边形三角形剖分的最低得分 枚举型区间dp C++实现
  • YOLOv8——测量高速公路上汽车的速度
  • 【IDEA】将光标移动到您上一次编辑的地方
  • 物联网迎来下半场,国产 IoTOS 打造企业级智能硬件云服务平台
  • vue 引入 esri-loader 并加载地图
  • Ubuntu磁盘不足扩容
  • NPM如何切换淘宝镜像进行加速
  • Linux入门学习:进程概念
  • ret2dl_resolve
  • gitlab默认克隆地址的修改
  • C# 第一章习题
  • [PHP内核探索]PHP中的哈希表
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • CAP理论的例子讲解
  • gulp 教程
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • markdown编辑器简评
  • nodejs:开发并发布一个nodejs包
  • Phpstorm怎样批量删除空行?
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • 创建一个Struts2项目maven 方式
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 力扣(LeetCode)965
  • 七牛云假注销小指南
  • 收藏好这篇,别再只说“数据劫持”了
  • 听说你叫Java(二)–Servlet请求
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 微信小程序设置上一页数据
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • hi-nginx-1.3.4编译安装
  • 湖北分布式智能数据采集方法有哪些?
  • (¥1011)-(一千零一拾一元整)输出
  • (阿里云万网)-域名注册购买实名流程
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (四) 虚拟摄像头vivi体验
  • (四)Controller接口控制器详解(三)
  • (转)人的集合论——移山之道
  • (转)树状数组
  • .apk文件,IIS不支持下载解决
  • .bat批处理出现中文乱码的情况
  • .describe() python_Python-Win32com-Excel
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET Micro Framework 4.2 beta 源码探析
  • .net开发引用程序集提示没有强名称的解决办法
  • .Net组件程序设计之线程、并发管理(一)
  • //usr/lib/libgdal.so.20:对‘sqlite3_column_table_name’未定义的引用
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @cacheable 是否缓存成功_Spring Cache缓存注解