编译原理——DFA与NFA及子集法将DFA转换成NFA

1. DFA与NFA的定义

(1) 概述

有穷自动机又称有限自动机,是识别正规文法的语言以及其所表示的集合,包括
DFA(Deterministic Finite Automata)确定的有穷自动机和NFA(Nondeterministic Finite Automata)不确定的有穷自动机。

(2) DFA

一个确定的有穷自动机M是一个五元组:

                  M = ( K , ∑ , f , S , Z ) M = (K, \sum,f,S,Z) M=(K,,f,S,Z)

(1) K K K 是一个有穷集,它的每个元素称为一个状态

(2) ∑ \sum 是一个有穷字母表,它的每个元素称为一个输入符号,所以也称其为输入符号表

(3) f f f是转换函数,是 K × ∑ → K K \times\sum \to K K×K上的映像。例如 f ( k i , a ) = k j ( k i , k j ∈ K ) 表 示 在 状 态 k i 输 入 一 个 字 符 a 即 转 换 到 状 态 k j f(k_{i},a)=k_{j}(k_{i},k_{j}\in K) 表示在状态k_{i}输入一个字符a即转换到状态k_{j} f(ki,a)=kj(ki,kjK)kiakj

(4)S ∈ K \in K K是唯一的初态

(5)Z ∈ K \in K K是唯一的终态

一个DFA可表示成状态图
在这里插入图片描述

(3) NFA

一个不确定的有穷自动机 M M M是一个五元组:

                               M = ( K , ∑ , f , S , Z ) M = (K,\sum,f,S,Z) M=(K,,f,S,Z)

(1) K K K 是一个有穷集,它的每个元素称为一个状态

(2) ∑ \sum 是一个有穷字母表,它的每个元素称为一个输入符号

(3) f f f是转换函数,是 K × ∑ ∗ → 2 k K \times\sum^* \to 2^k K×2k上的映像,其中 2 k 2^k 2k表示 K K K的幂集( ∑ ∗ = ∑ 0 ∪ ∑ 1 ∪ ⋯ ∪ ∑ n 其 中 ∑ 0 = ε , ε 是 空 串 \sum^*=\sum^0\cup\sum^1\cup\dots\cup\sum^n其中\sum^0=\varepsilon,\varepsilon是空串 =01n0=ε,ε)

(4) S ∈ K S\in K SK,是一个非空初态集

(5) Z ∈ K Z\in K ZK,是一个非空终态集

一个NFA也可表示成状态图
在这里插入图片描述

2. NFA转换成等价的DFA——子集法

(1) 依据:

设L为一个NFA接受的集合,则存在一个接受L的DFA

(2) 子集法:

首先定义两个运算:
1> ε − c l o s u r e ( I ) \varepsilon-closure(I) εclosure(I) ε 闭 包 , 状 态 集 I 中 的 任 意 状 态 S 经 任 意 条 ε 弧 能 够 到 达 的 状 态 的 集 合 \varepsilon闭包,状态集I中的任意状态S经任意条\varepsilon弧能够到达的状态的集合 ε,ISε
2> m o v e ( I , a ) : 状 态 集 合 I 的 a 弧 转 换 , 指 状 态 集 合 I 中 任 意 状 态 能 经 过 一 个 a 弧 到 达 的 状 态 的 全 体 move(I,a):状态集合I的a弧转换,指状态集合I中任意状态能经过一个a弧到达的状态的全体 move(I,a):IaIa

思路 :

DFA的每个转换都是确定的,而NFA中包含空串 ε \varepsilon ε,导致了它不确定。我们要做的就是合并空串 ε \varepsilon ε所导致的的等价状态从而消除空串。所谓等价状态即能通过若干个 ε \varepsilon ε连接的状态。如下图所示,状态0经过一条 ε \varepsilon ε到达状态1,经过两条 ε \varepsilon ε到达状态2,因此{0,1,2}等价,最后会合并成一个状态。而求某个状态 t t t 的等价状态就是在做 ε − c l o s u r e ( t ) \varepsilon-closure(t) εclosure(t)运算。注意:由于NFA中每个状态允许存在多条 ε \varepsilon ε出弧,且可能之间还存在非 ε \varepsilon ε弧。因此,NFA中的每个状态会重复出现在多个等价状态中。不容易直接通过求等价状态(结点)来求DFA
在这里插入图片描述
我们知道,由弧连接的两个结点都是状态,可以看作图对于图的构建来说,只需找出一个结点然后通过它的出弧找到其他结点(这个过程即 m o v e ( K , ∑ ) move(K,\sum) move(K,)运算),并对这些结点递归处理即可找到所有的结点,类似于图的广搜。对于NFA来说,我们可以先求出初始状态的等价状态 ε − c l o s u r e ( S ) \varepsilon-closure(S) εclosure(S)即第一个结点,然后通过它的出弧来找到其他状态,从而构建DFA。

第一步:求初始状态的等价状态 T 0 = ε − c l o s u r e ( S ) T_{0} = \varepsilon-closure(S) T0=εclosure(S)

第二步: 找到 T 0 T_{0} T0中所有出弧以及对应的状态(以下仅以出弧a为例) T e m p = m o v e ( T 0 , a ) ( a ∈ ∑ ) Temp = move(T_{0},a) (a\in \sum) Temp=move(T0,a)(a)。由于 T 0 T_{0} T0存在一条出弧a到达Temp,因此Temp必须作为一个状态。根据等价思想,可令 T 1 = ε − c l o s u r e ( T e m p ) T_{1} = \varepsilon-closure(Temp) T1=εclosure(Temp),即Temp的等价状态 T 1 T_{1} T1是NFA中新的状态 T 0 与 T 1 之 间 的 映 射 关 系 为 D ( [ T 0 ] , a ) = T 1 T_{0}与T_{1}之间的映射关系为D([T_{0}],a) = T_{1} T0T1D([T0],a)=T1

第三步:将求出的新状态再重复步骤二。直到得到的状态均已存在

最终得到新状态: T 0 、 T 1 、 T 2 、 T 3 … T n T_{0}、T_{1}、T_{2}、T_{3}\dots T_{n} T0T1T2T3Tn以及之间的映射关系 D ( [ T 0 ] , a ) = T 1 、 D ( [ T 0 ] , b ) = T 2 、 D ( [ T 2 ] , a ) = T 3 、 … D ( [ T n ] , a ) = T n D([T_{0}],a) = T_{1}、D([T_{0}],b) = T_{2}、D([T_{2}],a) = T_{3}、\dots D([T_{n}],a) = T_{n} D([T0],a)=T1D([T0],b)=T2D([T2],a)=T3D([Tn],a)=Tn


K = { T 0 、 T 1 、 T 2 、 T 3 … T n } K=\{ T_{0}、T_{1}、T_{2}、T_{3}\dots T_{n}\} K={T0T1T2T3Tn}
f = D f=D f=D
∑ = ∑ \sum=\sum =
S = T 0 S = T_{0} S=T0
Z = T n Z =T_{n} Z=Tn

则有 M D F A = ( { T 0 、 T 1 、 T 2 、 T 3 … T n } , ∑ , D , T 0 , T n ) M_{DFA} =(\{ T_{0}、T_{1}、T_{2}、T_{3}\dots T_{n}\},\sum,D,T_{0},T_{n}) MDFA=({T0T1T2T3Tn},,D,T0,Tn)

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值