32.4-8 给出一个有效算法,计算出某给定模式P的字符串匹配自动机的转移函数ϵϵ,所给出的算法运行时间应该是 O(m|∑|)O(m|∑|)
伪代码如下:
m=P.length
π=COMPUTE-PREFIX-FUNCTION(P)
for q=0 to m
for each character a in Σ
if P[q+1]==a
δ(q,a)=q+1
else if q==m or P[q+1]!=a
δ(q,a)=δ(π[q],a)
return δ
两层循环的内部在常数时间内完成,算法复杂度很容易看出是 O(m|∑|)O(m|∑|) 。正确性主要需要证明第7,8行,其他步骤都是显然的。第7、8行其来自于一个引理。
引理:如果 q=mq=m 或 P[q+1]≠aP[q+1]≠a ,则 δ(q,a)=δ(π[q],a)δ(q,a)=δ(π[q],a)。
证明:
q=mq=m 或 P[q+1]≠aP[q+1]≠a 时候,对模式的检索到此结束,下一个状态需重新置位。根据前缀函数的定义,对于 PqPq本身,我们有 σ(Pq)=π[q]σ(Pq)=π[q] 。所以对 PqPq 长度为 π[q]π[q] 的后缀串 ss , 同时也是 PqPq 相同长度的前缀。所以我们有 δ(q,a)=ϕ(s)=ϕ(π[q])=δ(π[q],a)δ(q,a)=ϕ(s)=ϕ(π[q])=δ(π[q],a)。
实际上这就是字符串匹配NFA转DFA的一个一般过程。