Python字符串处理算法 (三)

 有限状态机


一个有限状态机(FSMM 是一个 5-tuple,包括
Q:
有限的状态集合
q0:
初始状态
A:
可接受状态
SIGMA:
有限的输入字符
delta:
状态转移函数



用于字符串匹配的有限状态机的状态总数,其实和文本长度无关,只是模式字符串的长度而已,因为任意时候的当下状态,都是Pk个前缀匹配成功,k可以是1m(即P的长度),当km时,也就是匹配成功了。
因此我们可以有一个最终状态函数 phi,来描述有限状态机器的当下状态,这个函数有如下的递归表达式

phi(epsilon) = q0  
epsilon 是空输入)
phi(wa) = delta(phi(w), a)

可见 phi 是依赖于状态转移函数 delta 的,那么 delta 的表达式是什么呢,书中也给出了
delta(q, a) = sigma(qa)
其中  sigma(x) 叫做后缀函数,借用前面的Python版后缀定义来表示一下,就是
sigma(x) = max{k: x.endswith(P[0:k])}

状态函数和后缀函数之间的联系在书中有严格的数学证明,但用白话说一下很好理解,就是状态机当前的状态,假设为 k 的话,就说明 P k 个前缀匹配成功,k 可以是1m(即P的长度),当 k m 时,也就是匹配成功了。

代码也比较直白,除了下标有点绕,所以建议和书对照看,但是注意书中第922页的代码有误.


def finite_automation_matcher(t, delta, m):
        n = len(t)
        q = 0
        for i in range(0, n):
                q = delta[(q, t[i])]
                print "i %d, t[%d] %s, status %d"%(i, i, t[i], q)
                if q == m:
                        print "Pattern occured with shift %d"%(i-m+1)


def compute_transition_function(p, SIGMA):
        delta = {}
        m = len(p)
        for q in range(0,m+1):
                for a in SIGMA:
                        k=min(m,q+1)
                        while not (p[0:q]+a).endswith(p[0:k]):
                                k=k-1
                        delta[(q,a)]=k
        return delta

def test_fsm():
        t = "abababacaba"
        p = "ababaca"
        m = len(p)
        SIGMA = "abc"
        delta = compute_transition_function(p, SIGMA)
        finite_automation_matcher(t, delta, m)


最后可将结果跟书中Figure 32.7 对比一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值