Answers:
由于您希望“在不到30分钟的时间内将正则表达式转换为DFA”,我想您正在手工研究相对较小的示例。
在这种情况下,您可以使用Brzozowski的算法 ,该算法直接计算语言的Nerode自动机(已知等于其最小确定性自动机)。它基于导数的直接计算,并且还适用于允许相交和补码的扩展正则表达式。该算法的缺点是需要检查沿途计算的表达式的等价性,这是一个昂贵的过程。但是在实践中,对于一些小例子,它非常有效。
左商。令为A ∗的语言,令u为一个词。然后 ü - 1大号= { v ∈ 甲* | ü v ∈ 大号} 语言ù - 1大号称为左商(或左衍生物)的大号。
Nerode自动机。所述Nerode自动机的是确定性自动甲(大号)= (Q ,甲,⋅ ,大号,˚F )其中Q = { Ü - 1大号| Ü ∈ 甲* },˚F = { Ü - 1大号| Ü ∈ 大号}和过渡函数被定义,对于每个一∈,由式 (û - 1大号)⋅ 一个= 一个- 1(Ü - 1大号)= (Ú 一)- 1大号 当心这个相当抽象的定义。A的每个状态都是 L乘以一个单词的左商,因此是 A ∗的语言。初始状态是语言大号,和一组最终状态的是集所有剩下商的大号由一个字大号。
编辑。(2015年4月5日),我刚刚发现了一个类似的问题:存在什么算法可用于构建可识别给定正则表达式描述的语言的DFA?被问到cstheory。答案部分解决了复杂性问题。
J.-E. Pin在形式和完整性方面提供了更好的答案,但是我认为您的教授所暗示的“直觉”要说些什么。
在大多数情况下,最简单的方法是查看正则表达式,了解其接受的语言,然后利用自己的创造力/聪明才智来构建接受该语言的DFA。
除了其他人给出的算法外,没有简单的方法可以做到这一点,但是这里有一些准则可能被证明是有用的。
问问自己,我是否可以编写仅使用布尔值或很小的整数变量来接受此RE的程序?然后编写该程序,并将其转换为DFA,其中每个值组合都有一个状态。
查找正则表达式中您确定可以接受的部分,即“如果我看到此内容,那么我必须匹配RE的这一部分。” 不一定总会有很多,但是识别这些零件可以显示易于制作DFA的零件,因此您可以在真正需要不确定性的零件上花费更多时间。
NFA-> DFA的子集构造实际上并不复杂。因此,如果这是一项作业,而不是考试题,则只需编写实施代码,然后让您的程序将NFA转换为DFA可能会更快。如果您使用自己的代码,那么应该不会出现抄袭问题。
当您可以在算法需要很多步骤但结果显而易见的地方使用直觉时,请尝试“向前看”。
a(a|ab|ac)*a+
。您可以将其直接转换为要简化为DFA的NDFA,也可以将其标准化为立即映射到DFA的内容。