【发布时间】:2013-03-19 19:59:58
【问题描述】:
这是来自一个研究项目的 DFA。我们手动创建了 DFA。我们对什么是与 DFA 对应的正则表达式感兴趣。当然,可能有多个 与之对应的正则表达式;我们更喜欢更简单的。
【问题讨论】:
-
等待 B、E 上自循环的标签是什么
标签: regex regular-language fsm dfa
这是来自一个研究项目的 DFA。我们手动创建了 DFA。我们对什么是与 DFA 对应的正则表达式感兴趣。当然,可能有多个 与之对应的正则表达式;我们更喜欢更简单的。
【问题讨论】:
标签: regex regular-language fsm dfa
您在 B 和 E 的自循环上错过了 DFA 中的标签。但是因为您说 对于给定的 DFA,所以标签的唯一选择是两个循环上的 0。
您的 DFA 的正确正则表达式是:
(00* 10*1)* (1(0 + 10)* 1 1) ( 0 + 1 (00* 10*1)* 1 ( 0 + 10)* 1 1)*
简要说明:
您只有一个最终状态,即D。因此,如果字符串以D 结尾,则可以接受。
你注意到D 上的传入边缘标记为1 并且D 有一个标记为0 的自循环。
起始状态为A,因此字符串可以以0 或1 开头。实际上,A 上有两个循环。一个以 0 开头并穿过上图。
上层循环的 RE 是:00* 10*1
要理解这一点:
0 0* 1 0* 1
A-E loop on E E-F loop on F F-A
在下图中从A 到D。回复是1 (0 + 10)* 1 1
要理解这一点:
1 (0 + 10)* 1 1
A - B loop on B B-C C-D
DFA 的完整 RE 是:(answer)
(00* 10*1)* (1(0 + 10)* 1 1) ( 0 + 1 (00* 10*1)* 1 ( 0 + 10)* 1 1)*
要理解这一点:
(00* 10*1)* (1(0 + 10)* 1 1) ( 0 + 1 (00* 10*1)* 1 ( 0 + 10)* 1 1)*
^ ^ ^
upper loop A to D loop on D * for loop on D
( 0 + 1 (00* 10*1)* 1 (0 + 10)* 1 1 )*
^ D-A A-A A-B loop on B, B-c c-D
self loop on D
编辑正如@RedBaron 所评论的那样,这个正则表达式是否会生成字符串01110100110:
首先检查它是否被 DFA 接受:
A--0--> E--1---> F--1---> A---1---> B--0---> B---1-- ->C---0--- ->B---0---> B--1-->C---1---> D---0--->D
是的字符串被 DFA 接受。
如何从我在答案中给出的 RE 生成,下面我已经对齐了 RE 和字符串。
(00* 10*1)* (1(0 + 10)* 1 1) ( 0 + 1 (00* 10*1)* 1 ( 0 + 10)* 1 1)*
0^ 1^ 1 1 0100 1 1 0
只有你可能要理解的困难:(0 + 10)* 如何生成0100?对于以下检查:
(0 + 10)*重复三遍:
(0 + 10)(0 + 10)(0 + 10)
0 10 0
【讨论】:
00*开头的可以改成0+和for循环在BI认为(0+10)*是错误的因为00001010都创建循环
00* 可以写成0+ 因为上标的概念我不使用它...第二,B 有两个循环一个自循环0* 和其他@987654355 @ loop via C 所以在 (0 + 10)* 读取点 3 中结合起来
(0*(10)*)*结合吗?
(0+10)*如何生成0100(0 + 10)* == (0*(10)*)* == (0* + (10)*)*
Jack,这个 DFA 基本上可以有两个正则表达式。 首先可以是 AB*CD*A, 第二个可以是AE*F*
【讨论】:
您需要使用的算法描述为here。如果您对该主题更感兴趣,我强烈建议您阅读 Michael Sipser 的 Introduction to the Theory of Computation。
对于您的特定 DFA,按照您得到此正则表达式的算法:
[(010*1)*1(10*)110*1]*(010*1)*1(10)*110*
【讨论】:
10*110* 用于从 A-B-C-D 转换而没有 c-B 中的循环
1(0*(10)*)*110*我认为也涵盖了C和B之间的循环
0+10*1 是 A-E-F 的循环。所以你可以在这两个表达式前加上前缀
你得到(0+10*1)*10*110*没有循环和(0+10*1)*1(0*(10)*)*110*有它
最终的表达式是这样的
(0+10*1)*1(0*(10)*)*110*
用于从 A 到 D 的过渡
最后到达状态 D 你可以得到一个1,到达A 并重复整个过程
((0+10*1)*1(0*(10)*)*110*)(1((0+10*1)*1(0*(10)*)*110*))*
See it in action 获取此 DFA 的一些有效和无效字符串
澄清 - 此正则表达式基于 PCRE 接受的正则表达式。所以+ 表示字符串出现1 次或多次,* 表示出现0 次或多次,而| 表示OR
编辑 (0*(10)*)* 可以写成(0|(10))* 更好(感谢@grijesh-chauhan 为我指明了那个方向)。所以RE(基于PCRE)将是
((0+10*1)*1(0|(10))*110*)(1((0+10*1)*1(0|(10))*110*))*
【讨论】:
A --0--E--1---F--1---A---1---B--0---B---1--C---0---B---0---B--1--C---1---D---0---D