将NFA转换为正则表达式

时间:2013-11-19 01:11:10

标签: regex nfa

我在这个网站上发现了同样的问题,答案是PDF describing how to convert an NFA to a regex。但这不起作用,因为这种方法有一些条件:

  1. 从初始状态到所有其他状态都有转换,但没有 过渡到初始状态。
  2. 只有一个接受状态只有转换进入它(并且没有传出 转换)。
  3. 接受状态与初始状态不同。
  4. 除了初始状态和接受状态之外,所有其他状态都与所有其他状态相连 通过过渡国家。特别是,每个州都有自己的过渡。
  5. 在我的例子中,开始状态只是进入下一个状态而不是所有状态(例如q0进入q1但不进入q2,q3),并且转换到开始状态。

    那么将NFA转换为正则表达式的最简单方法是什么?我没有给出一个NFA示例,因为我没有特定的一个,只是一个普遍的问题,因为我遇到了这种DFA,其中启动状态与所有状态都没有关联,并且转换为开始状态。

    我想要一种通用算法来转换这种NFA。

1 个答案:

答案 0 :(得分:2)

答案是假设这些条件,因为可以修改任何NFA以满足这些要求。

对于任何类型的NFA,您可以添加一个新的初始状态q 0 ,它具有到原始初始状态的epsilon转换,并且还使用一个名为∅的附加转换符号(它们称之为空集符号,假设是与原始NFA中的任何符号不匹配的符号,从它到任何其他状态,然后使用这个新状态作为新的初始状态。请注意,这不会更改原始NFA接受的语言。这将使您的NFA满足第一个条件。

对于任何类型的NFA,您可以添加新的接受状态q a ,其具有来自原始NFA中所有接受状态的epsilon转换。然后将此标记为唯一的接受状态。请注意,这不会更改原始NFA接受的语言。这将使您的NFA满足第二个条件。

通过上述结构,通过设置q 0 != q a ,它满足第三个条件。

在您提供的链接中,第四个条件通过一个名为∅(空集符号)的特殊转换符号来解释,其中原始NFA中的实际字母不能匹配。因此,您可以使用此新符号将转换从每个状态添加到任何其他状态。请注意,这不会更改原始NFA接受的语言。

所以现在修改了NFA以满足这四个要求,您可以在那里应用算法将NFA转换为正则表达式,它将接受与原始NFA相同的语言。

编辑以回答进一步的问题

要在评论中回答您的问题,请考虑具有两种状态的NFA,q A 和q B 。 q A 是初始状态以及唯一的接受状态。我们有一个从q A 到符号为0的自身的转换。我们也从q A 到q B 转换为符号1.最后我们从q B 转换到q A with symbol 0。

可视化:

 0,1    
  |  1
->qA----->qB
  ^       |
  |-------|
     0

步骤2.当我们规范化NFA时,只需将新的初始状态(q init )指向q A ,并设置新的接受状态(q来自q A acc

步骤3.我们要删除q A 。所以q A 是算法中的q rip (第3页)。现在我们需要考虑进入q A 的每个状态以及从q A 退出的每个状态。在这种情况下,有两个状态指向q A ,即q init 和q B 。 q A 指向两种状态,即q B 和q acc 。通过该算法,我们用中的过渡q 替换 - > q rip - > q out 中的过渡q / sub> - > q out ,在中具有转换符号R dir + R (R rip ) * R out ,其中:

  1. R dir 是从中的q 到q out的原始过渡
  2. 中的R 是从中的q 到q rip的原始过渡
  3. R rip 是q rip的原始循环
  4. R out 是从q rip 到q out的原始过渡
  5. 所以在这种情况下,我们用q init替换转换q init - > q A - > q B - > q B ,带有转换符号(0 + 1)* 1。继续这个过程,我们将创建总共4个新过渡:

    1. q init - > q B :( 0 + 1)* 1
    2. q init - > q acc :( 0 + 1)*
    3. q B - > q B :0(0 + 1)* 1
    4. q B - > q acc :0(0 + 1)*
    5. 然后我们可以删除q A

      步骤4.我们要删除q B 。同样,我们识别中的q 和q out 。这里只有一个状态来到q B ,这是q init ,只有一个状态偏离q B ,这是q <子> ACC 。所以我们有:

      1. R dir =(0 + 1)*
      2. in =(0 + 1)* 1
      3. R rip = 0(0 + 1)* 1
      4. R out = 0(0 + 1)*
      5. 所以新的转换q init - &gt; q acc 将是:

          

        [R <子> DIR + R <子>在(R <子>撕裂)* R <子>出

             

        (0 + 1)* +(0 + 1)* 1(0(0 + 1)* 1)* 0(0 + 1)*

        我们可以删除q B

        步骤5.由于原始NFA中的每个州都已被删除,我们就完成了。所以最终的正则表达式如上所示。

        请注意,最终的正则表达式可能不是最优的(并且在大多数情况下它不会是最优的),这可以从算法中得到预期。一般来说,找到NFA(甚至是DFA)的最短正则表达式是非常困难的(尽管对于这个例子,很容易看出第一个组件已经覆盖了所有可能的字符串)

        为完整起见,接受相同语言的最短正则表达式将是:

          

        (0 + 1)*

相关问题