Shift-and 字符串匹配
基于位运算的字符串匹配算法。
我们令模式串为 $s$,长度为 $n$ ,文本串为 $t$ ,长度为 $m$ 。字符集大小为 $k$
无特殊说明时,字符串从 $0$ 位开始。
模式串匹配文本串
顾名思义,预处理在模式串中进行。而最终计算在文本串内进行。
预处理中,$B_{i,j}$ 表示字符在 $s$ 的第 $j$ 位是否为 $i$。
令 $P$ 表示文本串的匹配情况,$i$ 表示当前枚举到文本串的第 $i$ 位,$P_j$ 表示 $t$ 中 $[i-j,i]$ 与 $s$ 中 $[0,j]$ 是否相等。
考虑从 $i-1$ 到 $i$ 时转移 $P$,P=(P<<1|1)&B[s[i]]
根据定义,这是显然正确的。
我们发现这些操作都与二进制的位操作,所以可以用 bitset 优化。
复杂度预处理 $O(\dfrac{nk}{w})$,主算法 $O(\dfrac{mn}{w})$
主要适用于 $k$ 比较小,且模式串长度也不长的情况。
文本串匹配模式串
同样的,预处理在文本串内进行,主算法在模式串中进行。
预处理中,$B_{i,j}$ 表示字符在 $t$ 中的第 $j$ 位为是否为 $i$。
令 $P$ 表示文本串的匹配情况,$i$ 表示当前枚举到模式串的第 $i$ 位,$P_j$ 表示 $s$ 中 $[j-i,j]$ 和 $t$ 中 $[0,i]$ 是否相等。
考虑从 $i-1$ 到 $i$ 时转移,P=(P<<1)&B[s[i]]
$P$ 一开始的 $[0,m-n]$ 位为 $1$。
主算法的复杂度同样也为 $O(\dfrac{mn}{w})$。
考虑到一般情况下文本串的大小大于模式串。主要适用于字符集数量比较小,文本串的动态变化的情况。
例题1
http://acm.hdu.edu.cn/showproblem.php?pid=5972
解决了 KMP 不能解决的情况,
例题2
bzoj2628
动态维护 $B$ 数组。