Hash课堂笔记

Hash哈希笔记


概念

  1. Hash就是吧一个字母映射成一个数字(树,图,字符串都可映射)

  2. 通过映射的 Hash值 进行比较。

  3. 在映射 Hash值 可能会发生冲突,即不同字符串映射成一样的\(Hash\)值。失效。

  4. 对于字符串来说,我们常把字符串看成K进制数(k>26,k为质数!!),然后对一个大指数取摸,余数就是此字符串的 Hash值 。

  5. 有时也用自然溢出为代价加快效率。


判断字串是否相同

  • 题面

  • 给出一个字付串,每次询问两个字串是否相同

1.预处理

先预设要模的大质数位进制;

ll base = 131;
ll mod = 2123400401301379571;

之后对每个字串进行Hash预处理运算

for(int i = 1;i <= n; i++)
	hs[i] = (hs[i-1] * base+idx(s[i]))%mod;//idx(sp[i]):第s[i]个字符所映射的数字

预处理\(\ power\)数组, (\(\ power[i]\) 表示当前 \(k\) 进制下,\(k\)\(i\) 次方)

power[0] = 1;
for(int i = 1;i <= n; i++){
	(ll)power[i]=(ll)power[i-1]*k%mod;//%mod是减少预算量,否组数会特别大
}

举例( \(10\) 进制)

\(2345\),我只要 \(345\) ,那么就需要 \({2345-2000 = 2\times 10^3 +3\times 10^2+4\times 10^1+5\times 10^0 - 2\times 10^3}\)

由上述预处理可知,现在我们哈希数组 \(ha[]\) 中的数分别为

\[\begin{alignedat}{3} ha[1] & = 2\times10^0 \ 即2\\ ha[2] & = 2 \ \times10^1+3 \ \times10^0 \ 即23\\ ha[3] & = 2 \ \times10^2+3 \ \times10^1+4 \ \times10^0 \ 即234\\ ha[4] & = 2 \ \times10^3+3 \ \times10^2+4 \ \times10^1+5 \ \times10^0\ 即2345\\ \end{alignedat} \]

那么 \(后三位的字符应该是=2345-2000=345=ha[4]-ha[(2-1)]\times 10^{(4-2+1)}\) ;

同理 \(45 = ha[4] - ha[2]\times 10^{(4-3+1)}\)

那么 \(K\) 进制数也是如此,因此就有了下面的公式。


// l r 表示需要的区间的字符边界
int hash_interval(int l,int r){
 ans = ((ll)ha[r] - (ll)ha[l - 1]*power[r - l + 1]%mod+mod)%mod
 //power[i]:k进制数的i次方.
//最后+mod是防止负数,原理不会变。
}

再有,对上面公式的推论举个例子,方便以后复习和外人观看更好理解

举例

  • \(a,b,c,d,a\)

  • \(1,2,3,4,1\)

  • 进制:29,\((ll)mod\ :\ 2123400401301379571\)

\[\begin{alignedat}{3} ha[1] & = 1\times29^0(1) \\ ha[2] & = 1 \ \times29^1+2 \ \times29^0(12) \\ ha[3] & = 1 \ \times29^2+2 \ \times29^1+3 \ \times29^0(123)\\ ha[4] & = 1 \ \times29^3+2 \ \times29^2+3 \ \times29^1+4 \ \times29^0(1234)\\ ...\\ \end{alignedat} \]

  • \(ha[3-4]\)

\[\begin{alignedat}{3} ha[3-4]& = ha[4]-ha[2]\times29^2(34) \\ &=1234-1200(12\times 29^2)\\ & = 34 \end{alignedat} \]

注:我是用10进制进行举例,方便~

作者@Thorzy,转载请声明出处

posted @ 2020-12-27 14:35  zxsoul  阅读(135)  评论(0编辑  收藏  举报