字符串HASH
字符串hash入门 字符串hash 洛谷hash模板题 hash入门到精通-知乎
hash直观说就是将一个字符串映射到一个整数(hash值)。需要确定p和mod的值
形成hash映射后,有如下应用:
求有多少不同的串:相同的串一定对应相同的hash值,不同的串一般大概率对应的是不同的值(有可能产生冲突),所以求出有多少不同的hash值,就可以说有多少不同的串。
求一个字符串是否是另一个的子串: 这里hash比kmp稍慢,不过也比较方便。
求S1在S2中第一次出现的位置,就是得到 len(S1)之后依次枚举首位置,算出S2这段子串的hash值,再将其与S1的哈市比较。
ac自动机,后缀数组,manacher,exkmp(暂时还不会)
字符串哈希的三种映射函数
1.自动溢出取模(由于没有id(x)所以不是很安全
unsigned long long hash[N];
hash[i]=hash[i-1]*p(自动取模)
解释:
由于没有id(x), 令hash[1]=1。
unsigned long long hash[N]
定义一个unsigned long long
类型的变量,它的范围是在[0, 2^64) 内,这就相当于,当数超不过264-1后,它会溢出!这就相当于一个数模264的过程。
那么hash函数可以理解为:
hash[i]=(hash[i-1]*p)%(2^64)
这里P取一个大素数,一般习惯取1e9+7或1e9+9
安全指数:三星(所以并不是很安全)
2.字符串字符(加入id(x)
hash[i]=(hash[i-1]*p+idx(s[i]))%mod
解释:
id(x)的映射一般映射到正整数
hash[i]=(hash[i-1]*p+idx(s[i]))%mod
p取一个6到8位的素数(19260817),mod取一个大素数,一般取1e9+7或1e9+9
安全指数:四星 (还可以)
3.双hash(用两个hash代表一个值)
hash1[i]=(hash1[i-1]p+idx(s[i]))%mod1
hash2[i]=(hash2[i-1]p+idx(s[i]))%mod2
pair<hash1,hash2>表示一个字符串!
double hash
即取两个mod值,mod1和mod2
hash1[i]=(hash1[i-1]*p+idx(s[i]))%mod1
hash2[i]=(hash2[i-1]*p+idx(s[i]))%mod2
mod1一般取1e9+7,mod2一般取1e9+9为什么这么取?
1000000007和1000000009是一对孪生素数,取它们,冲突的概率极低!
安全指数:五星!(非常稳!但对于有些题时间复杂度可能不行)
小结:可以这么说,hash某种程度上就是乱搞,把hash函数弄的越没有规律越好,使得冲突的概率小到大部分数据都卡不掉。
•如果你开心,你想triple hash,ultra hash,rampage hash… 都没有问题!
但请注意,hash的维度越高,耗时越高,耗内存越大!一般情况下,single hash可以被hack掉,但double hash极难被hack掉, 用double hash足以解决问题