字符串哈希

字符串哈希
个人理解:字符串哈希就是将字符串中一个个字符用自己定义的哈希公式转化为一个个数字,因为哈希算法公式的特殊性自己取质数,很难有重复的转化数字。所以自己所取的数定义的公式就是哈希算法的关键。

基本哈希
给定一个字符串S=s1s2s3…sn,对字母s[i],我们规定f(i)=s[i]-‘a’+1。(也可以直接用s[i]的ascll对应值)

接下来是两个(一个)哈希的简单方式

自然溢出法

哈希公式:hash[i]=hash[i-1]*p+f( i )
首先我们定义一个哈希表
unsigned long long int hash[n]

然后定义一个哈希公式语句
hash[i]=hash[i-1]*p+f( i )
公式中的p就是自己定义的哈希公式,因为p为自己选取的质数值。

当hash数组从i=1开始计算,为了方便计算,通常将hash[0]=1。

因为unsigned long long 的范围自然溢出,相当于算出的数字自动对264-1取模,这样我们就可以避免重复的hash值。

单Hash方法

哈希公式:hash[i]=( hash[i-1] * p + f(i) ) % mod
浅显易懂相较于自然溢出方法多了个取模的过程,其实比较起自然溢出法只是从对264-1取模替代成我们自己取的数字取模。

其中p与mod均为质数,且有p<mod 。

并且我们应尽量取大值,因为取模的值取越大则重复的几率越小。

举例
如取p=10,mod=20200202,对字符串thy进行Hash
hash[0]=1;
hash[1] = (hash[0] * 3 + 19) % 20200202 = 22
hash[2] = (hash[1] * 3 + 7) % 20200202 = 73

 hash[3] = (hash[2] * 3 + 24) % 20200202 = 243

这样243就是 thy 的hash值。
介绍完一种方法接下来

实战环节

138. 兔子与兔子

很久很久以前,森林里住着一群兔子。

有一天,兔子们想要研究自己的 DNA 序列。

我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文字母)。

然后我们每次选择两个区间,询问如果用两个区间里的 DNA 序列分别生产出来两只兔子,这两个兔子是否一模一样。

注意两个兔子一模一样只可能是他们的 DNA 序列一模一样。

输入格式

第一行输入一个 DNA 字符串 S。

第二行一个数字 m,表示 m 次询问。

接下来 m 行,每行四个数字 l1,r1,l2,r2l1,r1,l2,r2,分别表示此次询问的两个区间,注意字符串的位置从1开始编号。

输出格式

对于每次询问,输出一行表示结果。

如果两只兔子完全相同输出 Yes,否则输出 No(注意大小写)。

数据范围

1length(S),m10000001≤length(S),m≤1000000

输入样例:

aabbaabb
3
1 3 5 7
1 3 6 8
1 2 1 2

输出样例:

Yes
No
Yes


题解:就是通过哈希公式求出区间哈希和和前缀和值出来后看下一串字符串中任意两段是否相等

核心代码:
1           for(i=1; i<=len; i++)
2         {
3             sum[i]=sum[i-1]*p+(s[i]-'a'+1);  //hash公式,p为任意自己制定的质数
4             p[i]=p[i-1]*p;         // 累乘p求出p的次方
5         }
6     

 随后根据比较输入的数的hash值和次方值是否相等来判断兔子是否一模一样

posted on 2020-02-02 21:41  JohnFllora  阅读(218)  评论(0)    收藏  举报