求解问题
寻找S中T出现的位置或次数。假设S的长度为n, T的长度为m, 通过枚举S长度为m的字串的hash值与T的hash值比较。此时使用滚动hash的优化使复杂度不为O(mn).
算法说明
滚动hash
取两个合适的素数b和h,假设字符串C = c1c2c3c4,定义hash函数:
H(C) = (c1bm-1 + c2bm-2 + c3bm-3 + ... + cmb0) mod h
其中b是基数, 相当于把字符串看做b进制。这项在计算S中m长的字串时,每向后滑动一个字符之后的字串的hash值和上一次字串的hahs值有如下关系:
H(S[k+1.. k+m]) = H(S[k..k+m-1] * b - skbm + sk+m)mod h
这样计算hash值就可以在O(n)的时间内算出S中所有位置对应的hash值,从而在O(m + n)的时间内完成字符串匹配。
Hit:实际使用时取h为264,使用long long int 自然溢出省去取模时间。
PS:原始的R-K算法还需要检查哈希值冲突,但这样会使算法复杂度退化为O(mn),比赛时只比较不检查。
模板
typedef unsinged long long int ull;