编译原理——正则表达式->NFA->DFA

编译原理太可怕啦,实在不敢掉以轻心!虽然上课恍恍惚惚,下课懵懵懂懂,但笔记必须得认认真真。(咳咳,进入正题:

正则表达式:

主要有三种:与(ab)、或(a|b)、闭包( (ab)* )

正则表达式->NFA:(Ɛ的意思是空,可以理解为两个直接连接

编译原理——正则表达式->NFA->DFA_第1张图片

 NFA->DFA:

编译原理——正则表达式->NFA->DFA_第2张图片

 以上就是简单三种类型的三种表达模式。如果还有点云里雾里,没关系,那下面来做一道题:

画出(abb*)*的DFA图

解题思路:

1、先尝试直接画DFA图,如果可以直接画出,再根据画的图跑一遍,如果行得通,则一般都是对的;

2、如果不能直接画DFA图,则取其次,画其简略版NFA图;

3、根据简略版的NFA图进一步画出DFA图;

4、求DFA图的最小化。

by the way,闭包的优先级最高,题目理解成(ab   b*)*。

解题步骤:

编译原理——正则表达式->NFA->DFA_第3张图片

尝试几遍之后,发现直接画出DFA图有些难度,则转而画其简略版NFA图(一定要确保画对,画完强烈建议对着正则表达式跑一遍)

接下来我们就要根据上图,画DFA图:

先给上面的五个圈圈(状态)起个编号,从左到右,依次为1,2,3,4,5;

s(1)={1,5};

s(2)={2};

s(3)={3,4,5,1}={1,3,4,5};

s(4)={4,5,1}={1,4,5};

s(5)={5,1}={1,5}。

解释:s(1)={1,5}的意思是,在状态1中,包含NFA中的哪些状态(这两个状态不是同个状态),即当你处在状态1时,你能去到哪里,因为Ɛ的意思是空,所以但凡是用Ɛ连接的,都可以看作同个状态,举个例子,状态4,它能去5,也能去1,当然还有自己,所以s(4)={1,4,5}。

列出这些之后,你已经成功了一半,接下来画状态转化图。NFA转DFA目标就是消除Ɛ,又因为只有a和b,所以状态转化的路径只有a和b。设s(1)为状态A,因为状态1是NFA中的起始状态,所以 s(1)即状态A,就是起始状态。

move(A,a)=s(2),设为状态B;

move(A,b)=Ø

解释:move(A,a)的意思是在状态A中,即{1,5},通过a能到达哪个状态,状态A中的1通过a能到达2,所以后继状态是s(2)。

状态B接着执行,

move(B,a)=Ø,

move(B,b)=s(3),设为状态C;

接着,

move(C,a)=s(2),即状态B;

move(C,b)=s(4),因为s(4)⊆ s(3),即状态C

解释:move(C,a)=s(2),状态C是s(3)={1,3,4,5},其中{1、3、4、5}中的1通过a能到达状态2,即s(2);move(C,b)=s(4),其中{1、3、4、5}中的4通过b能到达自身状态4,即s(4),但s(4)⊆ s(3),所以算是自己到达自己。

列表形式:

编译原理——正则表达式->NFA->DFA_第4张图片

DFA图:

编译原理——正则表达式->NFA->DFA_第5张图片

小tip:

如何确定始态和终态?NFA图中1是起始状态,所以s(1),即A是始态;NFA图中5是终止状态,则所有包含5的状态都是终态,状态A、B、C中AC都含有5,所以都是终态(双圆圈)。

做完了?还没有!最后一步还要检查DFA图是否已经最小。

DFA的最小化:

最小化:优化DFA,使其状态数最少。

要使状态数最少,则需要把一些状态进行合并,那哪些状态可以合并,哪些不可以呢?当这两种状态可区分时,就可以合并。

可以合并的条件(可区分):

1、同为终态或者同为非终态;

2、无论经过哪条路径得到的结果(后继状态)都是相同的。

对于本题,看列表,状态A和B,一个是终态一个是非终态,可区分,则不可合并;状态A和C,两个都是终态,但是状态A经过b时为空,状态C经过b时为C,后继状态不一样,可区分,则不可合并。说明以上DFA图已经是最小化。完结!(如果出现不可区分,可合并时,直接合并即可)

所以,你学fei了吗

编译原理——正则表达式->NFA->DFA_第6张图片

你可能感兴趣的:(其他)