形式语言与编译(二)NFA

正则语言

如果某个语言能被DFA识别,那么它就是正则的

例题1:

构造一个字母表为{0,1}的DFA,使其接受所有最多含有三个1的串。

例题2:

构造一个DFA,使其能够定义如下语言:

​ L={010,1} \(\Sigma=\{0,1\}\)

处理不了的话,可以引入一个特殊状态——死状态Qdie,这是严格要求的DFA

不严格的DFA则通常只写有意义可以到达的边,不可处理的边省略不写

对应到转移表(迁移表)的话,严格要求的话我们通常在表中不可到位置写qdie;不严格要求的话,我们通常就直接在表中用空项,表示不可处理

例题3:

字母表是\(\Sigma=\{0,1\}\),构造识别偶数个0和偶数个1的DFA.(DFA识别的一定是正则表达式,以后我就不说明了)

例题4:

\( L=\{w|w\in\{0,1\}^*\}\)且w 看做二进制数 能被5整除

例题5:

构造自动机DFA,让其能够识别正则串并且以01结尾的串

构造自动机DFA,让其能够识别正则串并且以101结尾的串

虽然DFA简单,但是表达能力不强,比如上述题,检测位数越多,状态图呈爆炸增长,\(2^5\),\(2^6\),\(2^7\),这么多状态几乎不可能编程序检测。因此提升DFA能力非常有必要。

NFA

非确定性的有限自动机

这个机器允许我们去[option] ,也就是遇到同样一件事有几条路径。

DFA可以看成函数,一一映射

NFA则可以看成多值"函数",一对多 NFA包含DFA

q3状态下,再继续读入0或者1,就"憋死了”

DFA里每一个输入都有明确的单一转移(1),NFA则就存在,转不成或者转的多(0,1,more)

面对NFA个多个路径,我们需要 遍历穷举

一般地,给出一个NFA,一个串,我们可以把所有的路径可以列出来,在列出来的所有路径中寻找happy path(我们需要的正确路径)。输入处理完,看是否是接受状态。

\(\delta_{NFA}\)是一个一对多的函数

\(\delta_{DFA}\)是一个一对一的函数

\(\delta(q_0,1)=q_0或q_1\) \(\delta(q_2,0)=空状态\) 这两个转移函数是NFA区别于DFA的最大不同

NFA遍历所有可能路径,有时候幸运,可能比较早找到happy path,有时候比较晚找到happy path;有时候则完全彻底遍历完,仍然找不到happy path,则拒绝这个串。

数学(形式)描述:

需要注意的是:

这个形式描述。(五元组中的其他4个形式描述与DFA差不太多)

因为\(\Sigma \cup \{\varepsilon\}\)的定义方式,这种NFA通常叫做\(\varepsilon\)的NFA

正常的NFA,这里的定义应该是\(\Sigma\) 即可。

引入带\(\varepsilon\) 的NFA是为了更方便的构造,人为构造会更加方便。后面我会说

NFA和\(\varepsilon\)的NFA 用程序实现起来不如DFA那么方便,后面会引入怎么把NFA转换成DFA。这在实验中是非常有必要实现的。

如何使用NFA来处理串?也就是遍历状态,当w被处理完了,看是否有当前状态是否是终止状态。简单。不讲了

NFA的扩展转移函数

实际核心就是将 串=子串+一个字符

与DFA的扩展转移函数实际并无多大差别。略

例题:

最终是\(\{q_0,q_2\}\)这个是接受状态(可能是有q2的原因,也就是其中有一个状态被接受就行)

最终的状态子集表达了所有的可能路径 。有一个状态accepted就可以啦

上面的严格数学定义:

posted @ 2020-06-15 16:57  _Sandman  阅读(1398)  评论(0编辑  收藏  举报