绘制最小DFA
的直接且简单的方法是什么,它接受与给定Regular Expression(RE)
相同的语言。
我知道可以通过以下方式完成:
Regex ---to----► NFA ---to-----► DFA ---to-----► minimized DFA
但是有没有捷径?喜欢(a+b)*ab
答案 0 :(得分:13)
虽然没有算法快捷方式从正则表达式(RE)绘制DFA,但是通过分析而不是通过派生可以实现快捷方式,它可以节省您绘制最小化dfa的时间。但是,在课程中你只能通过练习来学习。我举例说明我的方法:
(a + b)*ab
首先,考虑正则表达式的语言。如果在第一次尝试时难以确定什么是语言描述,那么找到可以用语言生成的最小可能字符串然后找到第二小的.....
保留一些基本正则表达式的记忆解决方案。例如,我有written here some basic idea to writing left-linear and right-linear grammars directly from regular expression.同样,您可以编写用于构造最小化的dfa。
在RE (a + b)*ab
中,最小的字符串为ab
,因为使用(a + b)*
可以生成NULL(^)
字符串。第二个最小的字符串可以是aab
或bab
。现在,我们可以轻松注意到语言的一个问题是,此RE语言中的任何字符串始终以ab
(后缀)结尾,而前缀可以是由a
和b
组成的任何可能的字符串。包括^
。
此外,如果当前符号为a
;那么一个可能的机会是下一个符号是b
和字符串结尾。因此,在dfa中,我们需要一个转换,以便在符号b
之后 符号 符号a
时,它应该移动到某些最终状态< / strong>在dfa。
接下来,如果一个新符号出现在最终状态,那么我们应该转移到某个非最终状态,因为b
之后的任何符号只能在语言中某些字符串的中间位置所有语言字符串都以后缀'ab'
终止。
因此,在这个阶段我们可以使用这些知识绘制一个不完整的转换图,如下所示:
- ►(Q <子> 0 子>)--- ---一个►(Q <子> 1 子>)--- b ----►((Q <子> f ))
现在,您需要了解:每个州都有一些含义,例如
(Q 0 )表示=开始状态
(Q 1 )表示=最后一个符号是'a',再多一个'b'我们可以转换到最终状态
(Q f )表示=最后两个符号为'ab'
现在想想如果符号a
出现在最终状态会发生什么。更多的是陈述Q 1 ,因为这个状态意味着最后一个符号是a
。 (更新过渡图)
--►(Q0)---a---►(Q1)---b----►((Qf))
▲-----a--------|
但假设符号a
不是符号b
,而是符号ab
处于最终状态。然后我们应该从最终状态转变为非最终状态。在这种情况下的当前转换图中,我们应该从最终状态Q f 转移到初始状态。(我们需要--►(Q0)---a---►(Q1)---b----►((Qf))
▲ ▲-----a--------|
|----------------b--------|
在字符串中接受)
a
此图表仍然不完整!因为Q 1 中没有符号a
的传出边。对于状态Q 1 上的符号a
,需要自循环,因为Q 1 表示最后一个符号是 a-
||
▼|
--►(Q0)---a---►(Q1)---b----►((Qf))
▲ ▲-----a--------|
|----------------b--------|
。
b
现在我相信所有可能的外出边缘都存在于Q 1 &amp;上图中的Q f 。一个缺失边是来自Q 0 的符号ab
的外出边缘。并且必须在状态Q 0 处有一个自循环,因为我们需要一个ab
序列,以便字符串可以被接受。 (从Q 0 到Q f 转换可以 b- a-
|| ||
▼| ▼|
--►(Q0)---a---►(Q1)---b----►((Qf))
▲ ▲-----a--------|
|----------------b--------|
)
{{1}}
现在DFA已经完成了!
当然,在最初的几次尝试中,该方法可能看起来很难。但是如果你学会用这种方法画出来,你会发现你的分析技能有所提高。而且你会发现这种方法是快速而客观的绘制DFA的方法。
*在我给出的链接中,我描述了一些更正规的表达式,我强烈建议您学习它们并尝试为这些正则表达式制作DFA。