NFA转DFA的算法在编译原理的课本上都有,只不过课本上的算法太拗口,不好记!我在这里边说的都很通俗,只要看得懂字的都会懂。在本篇文章里用一个例子来说明怎么实现NFA转DFA与DFA简化,NFA转DFA会讲的比较细,DFA简化只是大概带过。
有一个NFA,如图:
要是想把NFA转成DFA,首先需要构造一张表(最主要的就是这张表),如图:
上图没有给出全部的转换关系,当然,大家这么聪明,在看了构造表的算法之后就会自己构造转换表了。构造转换表的算法如下(表中的第一列是给为化简的DFA状态取的名字,第二列也是DFA中的状态,第三列和第四列是DFA在某一状态在读取a、b时跳转到的状态):
- 首先把NFA转换为上图所示的模样。
- 从NFA的初始状态开始,把从初始状态跳空能到的状态以及该状态跳空能到的状态填在第二列第二行中,直到没有新的状态能够由已得到的状态跳空得到为止,就如{X,1,2}。
- 第二列的状态分别对应NFA图来分别跳a,跳a后的状态填在Ia列以及跳a行对应的单元中,得到的状态再跳空,如果NFA对应的状态有跳空则把跳空后的状态也填入同一个单元格中,如上表的{1,3,2}。
- 跳b的情况也与跳a的情况类似,把第三步的跳a改成跳b即可。
- 经过3、4步得到的状态再把他们分别填在第二列中,用2-4的步骤来生成经他们读a、b能到的状态。
- 重复3-5。
- 当表中的所有状态都出现在第一列时说明表的构造已经完成了。
在构造了表之后就可以通过这个表来构造相应的DFA了(有X的是初态,有Y的是终态),在这里不再赘述怎么用表来构造DFA。
在构造了DFA之后就需要来化简它了,化简DFA的算法如下:
- 先分成非终态和终态两个大的状态。
- 再在这两个状态里边找跳a、b后所到的状态不在其所在集合里边的状态,把它单独作为一个状态分出去(即需要区分状态内部是否识别a、b)。
- 得到的新状态再分别使用步骤2的方法,直到没有新的状态产生为止(即所有的状态内部都能够识别a和b)。
上述所说的方法结合例子来看就更容易理解了!