nfa确定化 dfa最小化_词法分析 | DFA 的最小化:Hopcroft 算法

ef0eb14458bbbc8af482196a1eea75ab.png

通过前面对于词法自动生成部分的学习,我们已经掌握了如何从源码生成到 DFA 。

那么为什么要对 DFA 进行最小化处理呢?

下面给出一个例子:

如下是我们之前写出的 a(b|c)* 的 NFA:

5ea4693c319af61d5a7e2d22031ca18c.png

它可以对应转换成如下的 DFA:

2522a86cdbca144a8f8b4222621026a3.png

在上面的 DFA 中非接受状态和接受状态是不能够合并的,因为如果合并,就会接受一个 ε 串,这是明显不正确的。但是如果同样是接受状态或者同样是非接受状态的话就有可能。例如可以将 q2 和 q3 进行合并,得到一个新的接受状态 q4。得到新的 DFA,如下:

b5061a67a1a714f2a5660a3409218435.png

之后,我们还可以再对 q1 和 q5 进行融合得到 q5。

3975ea0ad44df117b60f13b8516794b7.png

这就是最终的状态最少的 DFA 。

最小化得到状态最少的 DFA 的好处在于,因为 DFA 最后的代码实现是在作为内部的一个数据结构表示,如果状态和边越少,则它占用的计算资源(内存、cache)会更少 ,可以提高算法的运行效率和速度。

Hopcroft 算法

//基于等价类的思想

232d67e9a85f6ebf7aeb20b68db988e6.png

q1, q2, q3 都有对状态 a 的转移,但是 q1 和 q2 转移到了同样的一个状态 S2, q3 转移到了 S3。所以 q1, q2 可以看做一组,因为它们对 a 的行为是一致的,都到了 S2。q3 单独一组。所以 a 这个字符将 S1 切为了两个子集。这就是等价类的思想。

Hopsroft 算法就是先根据非终结状态与非终结状态将所有的节点分为 N 和 A 两大类。 N 为非终结状态,A 为终结状态,之后再对每一组运用基于等价类实现的切割算法。

举个例子:

4706b1a929a001516f56e85692aa2df9.png

对于之前给出的 DFA 的例子,我们首先将其切分为 N 和 A, N 是 q0, A 是 {q1, q2, q3}。

在 A 中,就字符 b 的状态转移,每个节点最后得到的都还是 A 这个状态,无法对 q1, q2, q3 进行区分。同理,c 也不能这三个节点进行切分。所以就将这三个节点融合为一个新的节点 q4。

3f664ee7a401f80dc0c3e0b210a2d27f.png

再给一个例子:

035b7718d701dd4936907c9d7b634a16.png

这个算法的正则表达式是 fee 或者 fie,可以通过 fee 或 fie 到达终结状态。

N : {q0, q1, q2, q4}

A : {q3, q5}

在 N 中 q0 和 q1 在接受 e 的条件下最终得到的状态还是在 N 的内部。所以可以将其根据 e 拆分成 {q0, q1}, {q2, q4}, {q3, q5}

对于 q2 和 q4 都可以接受 e ,而且最终达到的状态一致,所以不能再进行切分。

q0 和 q1 ,在接受 e 的时候, q0 最终得到还是在 {q0, q1}这个状态的结合中, q1 却会落在 {q2, q4} 的状态中,所以可以将 q0 和 q1 分为 {q0}, {q1}。

9300979558aa2062d864fbe6d308667d.png

原文链接:

  • 编译原理 - 网易云课堂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值