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=m q = m 或 P[q+1]≠a P [ q + 1 ] ≠ a ,则 δ(q,a)=δ(π[q],a) δ ( q , a ) = δ ( π [ q ] , a ) 。
证明:
q=m
q
=
m
或
P[q+1]≠a
P
[
q
+
1
]
≠
a
时候,对模式的检索到此结束,下一个状态需重新置位。根据前缀函数的定义,对于
Pq
P
q
本身,我们有
σ(Pq)=π[q]
σ
(
P
q
)
=
π
[
q
]
。所以对
Pq
P
q
长度为
π[q]
π
[
q
]
的后缀串
s
s
, 同时也是
Pq
P
q
相同长度的前缀。所以我们有
δ(q,a)=ϕ(s)=ϕ(π[q])=δ(π[q],a)
δ
(
q
,
a
)
=
ϕ
(
s
)
=
ϕ
(
π
[
q
]
)
=
δ
(
π
[
q
]
,
a
)
。
实际上这就是字符串匹配NFA转DFA的一个一般过程。