目录
带通配符的单模式匹配
平常的单模式匹配就是给出一个模式串 t,给出一个文本串 s,问 s 中能够在哪些位点完全匹配 t,这个用 KMP 可以很好地解决。但是如果在模式串和文本串中有一些通配符,也就是这些符号匹配什么都可以,那这样就解决不了了。比如说 t=a*b
,s=aebr*ob
,其中 *
表示通配符,那么 t 在 s 中可以匹配的位点为 1 5
(下标从 1 开始)。
解决办法本质上是把匹配转变为一个数学公式 G(x),表示模式串在原串的 x 处的匹配公式,并且这个 G(x) 满足 ,且当 G(x)=0 时表示可以匹配。一般 G(x) 由一些子公式组成。
对于带通配符的单模式匹配问题,我们可以设子函数 p(a, b) 表示 t[a] 和 s[b] 的匹配函数,p(a, b) 和 G 具有一样的性质,所以我们的主要目标就是如何构造函数 p,使得它满足这个性质。比如对于这个问题,我们可以把 *
设为0,然后设
,那么满足
,并且仅当 t[a]=s[b] 或两个中有通配符时才成立 p(a, b)=0 ,其余情况都大于 0 。所以有
,可以证明这个 G(x) 满足上面的限制。
进一步,我们把模式串 t 翻转(这是为了凑出常数),然后公式就变为 ,发现 ,对于特定的 x 是一个常数,那把 p 带入展开之后,这不就是一个很长的卷积和式么。用几次 FFT 加速,就可以算出所有的 G(x),然后一一判断是否等于 0 来决定是否匹配。
其实一般的单模式匹配也可以这么做,只要改一下 p 函数,改成 就可以了。