[编译原理随记]NFA转DFA子集构造算法

上级文章

[编译原理随记]正则表达式记号和状态图:https://blog.csdn.net/qq_28033719/article/details/107067798


准备知识

有穷自动机:

可以理解为更加一般化的状态转换图,分为确定有穷自动机(DFA),不确定有穷自动机(NFA)。

一般化:

数学中指普遍性,从已有对象小集合到已有对象大集合过度思想,相似于泛化。

不确定有穷自动机(NFA):

其实是输入有穷序列时候,输入导致转换的状态不确定。

比如说(a|b)*abb,(a|b)*就不确定输入导致的状态如何转换,比如我输入了 a ,我不知道下一个状态是 0 还是 1。

状态转换图:

确定有穷自动机(DFA):

输入有穷序列时候,能够确定输入导致的状态。

比如aa*|bb* ,我输入了 a 那肯定下一个状态是 2 ,它的状态转换图:

子集构造算法

DFA是比较容易建立程序的,所以将NFA转为一个DFA是很重要的。

我们要用到式子:ε-closure(S),ε-closure(move(T , a))

ε-closure(S)

表示由状态s经由条件ε可以到达的所有状态的集合。

{1,2,3,4} = ε-closure(S) 表示:{1,2,3,4}状态(接收状态,不一定是流程终点,是到达的点),就是从S状态(叫做开始状态,开始不一定是流程起点,是出发的点)转换成的状态集合,即ε-closure(S)移动任意个 ε 状态是{1,2,3,4}

ε-closure(move(T , a)) 

其中move(T, a)意思:假设当前状态 T = {1,2},然后输入 a ;

ε-closure(move(T , a)) 就是 当前状态 T = {1,2},然后输入 a 记为move(T, a),然后得出状态假设为{3,4},即:

ε-closure(move(T , a))  = ε-closure(move({1,2} , a))  = {3,4}

{3,4} 就是 当前状态:{1,2} 输入了 a 之后的状态,也意味着 {1,2} 所处的状态是可以输入a的(其中有任意个输入为 ε 的操作)。

假设只有1,2才输入a,那么:ε-closure(move(T , a))  = ε-closure(move({1,2,5,6,7,8,9} , a))  = {3,4},集合里面5,6,7,8,9和1,2的状态一致,只不过不能输入a的意思。

例子:

比如说 (a|b)* abb 的另一个 NFA 状态图:

1、开始

-- 我要从开始输入一个a,首先 Start 状态是:

ε-closure(0) = {0,1,4,2,7} ,因为这些状态都是从start开始输入任意个 ε 得到的状态,开始状态 0 也等同于输入任意个 ε 后的状态 {1,4,2,7}。

-- 然后输入a操作的状态是:

ε-closure(move({0,1,4,2,7} , a))

因为图中只有 2 , 7状态才可以输入 a,所以输入 a 之后状态是 3 , 8,得

ε-closure(move({0,1,4,2,7} , a)) = ε-closure({3,8})

同时因为  {3,8} 和 move({3,8},ε)(输入任意个  ε ,其实 ε-closure 就表明了)状态时一致的,因此得出:

ε-closure(move({0,1,4,2,7} , a)) = ε-closure({3,8}) = {1,2,3,4,6,7,8} (里面掺入了很多空串输入的状态)

2、把可能的状态都列出来(怎么想办法列出来可能要学学集合,或者靠玄学):

Start = {0,1,4,2,7}    
MoveA = {1,2,3,4,6,7,8}   
MoveBCycle = {1,2,4,5,6,7}  
MoveB1 = {1,2,4,5,6,7,(注意)9} 
MoveB2 = {1,2,4,5,6,7,(注意)10}

3、编写Dtran表格(有点像真值表)

怎么编写,就是使用 ε-closure(move(T , a))  和  ε-closure(move(T , b))  得出状态,

然后写出 (A 状态,输入 a | b) 计算如下,其他可以照推:

ε-closure(move(A , a)) = B // 具体计算省略
ε-closure(move(A , b)) = C

然后将 A B C D E 状态和输入 a | b 的结果,编写成表格为:

已经可以看到,我在A状态,如果输入 a 那么下一个状态一定是 B (完全确定了),其他同理。

4、画状态图

根据表格连线就行了,弄成DFA的状态图,肯定写的出程序了:

图里面,比如 A \overset{b}{\rightarrow} C这个状态就是根据 Dtran 表格,表格也因为 ε-closure(move(A , b)) = C 所以得出A \overset{b}{\rightarrow} C


下级文章:

[编译原理随记]正则表达式转为DFA状态图(Thompsion构造法):https://blog.csdn.net/qq_28033719/article/details/107084565

猜你喜欢

转载自blog.csdn.net/qq_28033719/article/details/107068996