首先,我会以我自己的方式回答这个问题。然后,我将解决您转换为确定性有限自动机的问题。
我们可以编写一组方程并求解 q2 以查看哪个正则表达式导致该状态。考虑以下系统:
(q1) = (q2)a + e
(q2) = (q1) + (q3)(a + b)
(q3) = (q1)a + (q3)b
我们要解决导致接受状态的原因,所以让我们首先消除不接受状态:
(q1) = (q2)a + e
(q2) = (q2)a + e + (q3)(a + b)
(q3) = (q2)aa + a + (q3)b
为了消除 (q3),我们可以使用规则 (x) = r + (x)s (x) = rs* 然后代入:
(q1) = (q2)a + e
(q3) = ((q2)aa + e)b*
(q2) = (q2)a + e + ((q2)aa + a)b*(a + b)
= (q2)a + e + (q2)aab*(a + b) + ab*(a + b)
= (q2)[a + aab*(a + b)] + [e + ab*(a + b)]
= (e + ab*(a + b))(a + aab*(a + b))*
= (e + ab*(a + b))(a(e + ab*(a + b)))*
我们恢复的正则表达式基本上是这样描述的:
通过空转换或通过 q3 到达 q2;然后,通过转到 q1 并重复第一部分回到 q2。您可以根据需要多次执行此操作。
你是怎么写系统的?
- e可以达到初始状态
- 如果表达式 r 上存在从状态 q 到状态 q' 的转换,则 q' = (q)r
- 如果可以通过多种方式达到某个状态,请使用 + 并包含所有方式
要确定一个有限自动机,请考虑每个状态子集并随时添加转换。我们从仅包含初始状态的子集 {q1} 开始。
/------------------------------------\
| __ |
V / \ |
{q1} -a-> {q1,q3} -a-> {q1,q2,q3} a |
| | | ^__/ |
b b b |
| __ | | |
V / V V | |
{ } b {q2,q3} <--------/ |
^ \__/ \ |
| \-a->{q1,q2}-----a----/
| |
\----------b----------/
添加状态和转换的规则是:
- 始终添加初始状态 {qi}
- 对于输入字母表中的每个状态 {q1,q2,...,qn} 和每个符号 x,添加从 {q1,q2,...,qn} 到 {q1',q2', 的转换。 ..,qn'} 在 x 上,其中 q1', q2', ..., qn' 可以从 q1, q2, ..., qn 通过恰好消耗一个 x(可能还有几个 e-transitions)到达
- 如果状态 {q1',q2',...,qn'} 不在您的自动机中,请添加它,然后在该状态上重复此过程
- 重复上述操作,直到添加了所有必要的状态,并且所有状态都针对输入字母表中的每个符号进行了转换。
注意:在上面的自动机中,我没有展示死状态 { } 上的转换。所有源自死状态的转换都以死状态终止。
我的 {q1} 类似于你最上面的 (OK)。我的 { } 类似于您的 HOLE。我的 {q1,q3} 类似于您的 NOT。我的 {q2,q3} 类似于你最右边的 OK。
但是 - 我的 {q1,q2,q3} 与您最底层的 OK 不同。为了让你的和我的一样,在符号 b 上添加一个从最底部的 OK 到最右边的 OK 的过渡。
请注意,我的 {q1,q2} 是多余的,相当于我的 {q1}; {q1,q2} 之外的所有转换都与 {q1} 之外的那些转换相同。真的,由于从 q1 到 q2 的电子转换,我应该将 {q1,q2} 设为初始状态,但无论如何 - 你明白了。
您的 DFA 不正确的原因是,在 NFA 中,总是有机会“搞砸”并最终陷入困境。在您的自动机中,您可以到达最底部的 OK 然后进行设置。