在没有epsilon的情况下将NFA转换为DFA

时间:2016-03-08 00:07:22

标签: computer-science finite-automata computation-theory

根据我的理解,始终需要使用epsilon将NFA转换为DFA。 是否可以将NFA转换为DFA?如果是这样,那么DFA会是什么样子?

enter image description here

1 个答案:

答案 0 :(得分:3)

NFA没有“ε状态”。它们具有“epsilon过渡”:使用epsilon字母标记的过渡,表示该过渡不消耗任何输入字符。 NFA图不需要包含任何epsilon转换。

Epsilon转换由编译器生成,该编译器将正则表达式转换为NFA图。它们有助于表示与可选匹配对应的旁路路径。如果您有一个没有任何可选项的正则表达式,例如ab,则NFA图表不会(必须)包含任何epsilon边缘。

NFA模拟和NFA到DFA转换的一个重要概念是“epsilon闭包”:一组状态可通过跟随epsilon转换从状态到达。如果任何状态S在闭包中,并且该状态具有到某个状态T的epsilon转换,那么T也在闭包中。因此“epsilon关闭”。

我们构造了一组NFA状态来处理NFA图在同一输入字符上有多个转换到多个状态的模糊性。然后我们执行epsilon闭包来处理存在转换的额外歧义而不消耗输入符号,表示可选匹配。

NFA模拟动态构造NFA状态集; NFA到DFA“子集构造”预先计算这些集合,并将它们转换为DFA图形中的节点。

DFA,非正式地,一步一步。

要将您的NFA图表转换为DFA,我们首先从空白平板开始。我们没有NFA国家。箭头告诉我们NFA从状态1开始。我们问自己,NFA状态在由状态1组成的集合的epsilon闭包中是什么?我们注意到:没有epsilon过渡。所以闭包集是{ 1 }。到目前为止,我们的DFA计算机为空,因此我们将此集{ 1 }设为S0,并将该对象称为a:DFA的初始状态。

既然我们有DFA状态,我们会问自己:对于每个输入字母字符,哪些转换超出此状态?我们首先评估S0。从代表NFA状态{ 1 }的集a开始,我们计算可在符号{ 1, 2 }上到达的NFA状态集。这些状态为1,因为aa上指向自身,并在{ 1, 2 }上转换为2。设置此转换后,我们需要考虑epsilons:我们需要通过计算其epsilon闭包来扩展该集合。由于没有epsilons,所以无所事事。我们有S1,我们会将该状态称为DFA的州 a b NFA set S0: S1 ? { 1 } S1: ? ? { 1, 2 } 。到目前为止,我们已经有了DFA的新图片:

S0

我们知道S1上的a转换为b。我们还不知道它对S1的作用,我们还没有考虑过b的转换。

我们接下来转到b(在评估S0的背景下)。在{ 1 }上,{ 2 }之外的状态可由{ 2 }集合组成。再次,epsilon-closing对此没有任何作用。并且S2看起来不像任何现有的DFA状态,因此我们建立了新状态 a b S0: S1 S2 { 1 } S1: ? ? { 1, 2 } S2: ? ? { 2 }

S0

现在我们已完成S1,因此我们转到下一个未完成状态{ 1, 2 },其中包含NFA集a。我们问,在消耗{ 1, 2 }时,可以从这个集合中获得哪些州?答案是{ 1, 2 }。这个epsilon闭包是{ 1, 2 }。我们注意到:S1S1相同。因此,a a b S0: S1 S2 { 1 } S1: S1 ? { 1, 2 } S2: ? ? { 2 } 上转换为自身:

S1/b

然后我们考虑{ 1, 2 }。消费b的{​​{1}}可以达到什么样的集合?答案是:{ 1, 2 }。因此,S1也会在b上转换为自身。

      a   b
 S0: S1  S2   { 1 }
 S1: S1  S1   { 1, 2 }
 S2:  ?   ?   { 2 }

现在S2/a很有趣。 {2}在a上没有任何转换:集合为空。我们可以用各种方式表示这种情况,其中之一就是我们创建了一个名为E的集合(错误)。如果在状态S2中看到a,那么这是一个错误;机器不接受这个角色。

      a   b
 S0: S1  S2   { 1 }
 S1: S1  S1   { 1, 2 }
 S2:  E   ?   { 2 }
  E:          { }

对于S2/b,我们看到{ 2 }过渡到{ 1 }{ 1 }只是S0

      a   b
 S0: S1  S2   { 1 }
 S1: S1  S1   { 1, 2 }
 S2:  E  S0   { 2 }
  E:          { }

如果机器进入状态E,它就会卡在那里,所以我们可以像这样填写条目:

      a   b
 S0: S1  S2   { 1 }
 S1: S1  S1   { 1, 2 }
 S2:  E  S0   { 2 }
  E:  E   E   { }

最后,我们注意到在原始NFA中,状态2是接受状态。因此,在DFA中,NFA集包含状态2的任何状态都是接受状态。

      a   b  acc?
 S0: S1  S2        { 1 }
 S1: S1  S1   y    { 1, 2 }
 S2:  E  S0   y    { 2 }
  E:  E   E        { }

如果机器进入状态E,则表示永久性故障。 (向DFA提供输入的人可能会注意到这种情况并停止喂食。)