算法:字符串哈希

3 阅读1分钟

字符串哈希

字符串Hash的目的是,如果我们判断两个字符串是否相等,就直接看它们对应的hash值是否相等。从而达到,子串的Hash值的时间为 O(1),进而可以利用“空间换时间”来节省时间复杂的。

一定不能使用hash来定义数组

自然溢出:

unsigned long long h[n];

h[i] = h[i-1] * p + ss[i];

利用unsigned long long 的范围自然溢出,相当于自动对pow(2,64) - 1 取模;

单Hash方法:

hash[ i ] = hash[ i − 1 ] *p + s [ i ] % mod

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

对于此种Hash方法,将p和mod尽量取大即可,这种情况下,冲突的概率是很低的

双Hash方法:

h a s h 1 [ i ] = ( h a s h 1 [ i − 1 ] ) ∗ p + i d *( s [ i ] ) % mod

h a s h 2 [ i ] = ( h a s h 2 [ i − 1 ] ) ∗ p + i d * ( s [ i ] ) % mod2

hash结果:< h a s h 1 [ n ] , h a s h 2 [ n ] >

某一个区间的hash值求法(假设字符串从1开始):

hs[0] = 0;

hs[1] = hs[0] * p + s[1];

hs[2] = hs[1] * p + s[2] = hs[0] * p * p + s[1] * p + s[2];

hs[3] = hs[2] * p + s[3] = hs[0] * p * p * p + s[1]pp + s[2] * p + s[3];

hs[4] = hs[3] * p + s[4] = hs[0] * p * p * p * p + s[1] * p * p * p + s[2] * p * p + s[3] * p + s[4];

区间公式为:hs[r] - hs[l-1] * p ^ (r - l + 1);

预处理p的n次方可以节约时间;

hx[i]=hx[i-1]*p+s[i];
pre[i]=pre[i-1]*p;//预处理