网站大量收购独家精品文档,联系QQ:2885784924

2.2字符串中的哈希.pdf

  1. 1、本文档共13页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多

字符串中的哈希

主讲人:邓哲也

字符串中的哈希

假设有n个长度为L的字符串,问其中最多有几个字符串

是相等的。

直接比较两个长度为L的字符串是否相等时间复杂度是

O(L)的。

22

因此需要枚举O(n)对字符串进行比较,时间复杂度O(nL)

如果我们把每个字符串都用一个哈希函数映射成一个整数。

问题就变成了查找一个序列的众数。

时间复杂度变为了O(nL)

字符串中的哈希

一个设计良好的字符串哈希函数可以让我们先用O(L)的时

间复杂度预处理,之后每次获取这个字符串的一个子串的哈

希值都只要O(1)的时间。

这里我们就重点介绍BKDRHash

BKDRHash

BKDRHash的基本思想就是把一个字符串当做一个k进制数

来处理。

intk=19,M=1e9+7;

intBKDRHash(char*str){

intans=0;

for(inti=0;str[i];i++)

ans=(1LL*ans*k+str[i])%M;

returnans;

}

BKDRHash

假设字符串s的下标从1开始,长度为n。

ha[0]=0;

for(inti=1;i=n;i++)

ha[i]=(ha[i-1]*k+str[i])%M;

我们知道ha[i]就是s[1..i]的BKDRHash

那么现在询问s[x..y]的BKDRHash,你能快速求解吗?

BKDRHash

注意到ha[y]=s[1]ky-1+s[2]ky-2+…+s[x-1]ky-x+1+

s[x]ky-x+…+s[y]

注意到ha[x-1]=s[1]kx-2+s[2]kx-3+…+s[x-1]

而我们要求的s[x..y]的哈希值为s[x]ky-x+…+s[y]

可以发现s[x..y]=ha[y]-ha[x-1]ky-x+1

因此我们预处理出ha数组和k的幂次,每次询问s[x..y]

的哈希值,只要O(1)的时间。

边学边练

阿轩在纸上写了两个字符串,分别记为A和B。利用在数据结构与算法课

上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”

与“字符串B”匹配的长度。

不过阿轩是一个勤学好问的同学,他向你提出了Q个问题:在每个问题中,

他给定你一个整数x,请你告诉他有多少个位置,满足“字符串A从该位

置开始的后缀子串”与B匹配的长度恰好为x。

例如:A=aabcde,B=ab,则A有aabcde、abcde、bcde、cde、de、e这6个

后缀子串,它们与B=ab的匹配长度分别是1、2、0、0、0、0。因此A有4

个位置与B的匹配长度恰好为0,有1个位置的匹配长度恰好为1,有1个位

置的匹配长度恰好为2。

1≤N,M,Q≤200000

边学边练

核心问题就是:给定两个字符串A,B。

求出A的每个后缀子串和B的最长公共前缀。

标准做法是扩展KMP,时间复杂度线性。

我们来用Hash试试看。

边学边练

前面已经提到,我们可以用O(n)预处理O(1)处理出一个子

串的哈希值。

求字符串A[i..n]与字符串B[1..m]的最长公共前缀?

二分!

二分长度mid

计算出A[i..i+mid-1]和B[1..mid]的哈希值,比较是否

相等。

因此时间复杂度是O(logn)的!

边学边练

llgetha(intx,inty){

returnha[y]-ha[x-1]*p[y-x+1];

文档评论(0)

133****9720 + 关注
实名认证
内容提供者

物业管理师证持证人

该用户很懒,什么也没介绍

领域认证该用户于2023年04月23日上传了物业管理师证

1亿VIP精品文档

相关文档