【问题标题】:What's the regex corresponding to this DFA?这个 DFA 对应的正则表达式是什么?
【发布时间】:2013-03-19 19:59:58
【问题描述】:

这是来自一个研究项目的 DFA。我们手动创建了 DFA。我们对什么是与 DFA 对应的正则表达式感兴趣。当然,可能有多个 与之对应的正则表达式;我们更喜欢更简单的。

【问题讨论】:

  • 等待 B、E 上自循环的标签是什么

标签: regex regular-language fsm dfa


【解决方案1】:

您在 B 和 E 的自循环上错过了 DFA 中的标签。但是因为您说 对于给定的 DFA,所以标签的唯一选择是两个循环上的 0

您的 DFA 的正确正则表达式是:

(00* 10*1)* (1(0 + 10)* 1 1) ( 0 + 1 (00* 10*1)* 1  ( 0 + 10)* 1 1)*

简要说明:

  1. 您只有一个最终状态,即D。因此,如果字符串以D 结尾,则可以接受。 你注意到D 上的传入边缘标记为1 并且D 有一个标记为0 的自循环。

  2. 起始状态为A,因此字符串可以以01 开头。实际上,A 上有两个循环。一个以 0 开头并穿过上图。
    上层循环的 RE 是:00* 10*1

    要理解这一点:

      0     0*           1      0*            1  
    
     A-E   loop on E     E-F    loop on F     F-A
    
  3. 在下图中从AD。回复是1 (0 + 10)* 1 1
    要理解这一点:

     1        (0 + 10)*    1     1
     A - B    loop on B    B-C   C-D      
    
  4. 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都创建循环
  • @RedBaron 是的00* 可以写成0+ 因为上标的概念我不使用它...第二,B 有两个循环一个自循环0* 和其他@987654355 @ loop via C 所以在 (0 + 10)* 读取点 3 中结合起来
  • 不应该和(0*(10)*)*结合吗?
  • (0+10)*如何生成0100
  • @RedBaron 是 (0 + 10)* == (0*(10)*)* == (0* + (10)*)*
【解决方案2】:

Jack,这个 DFA 基本上可以有两个正则表达式。 首先可以是 AB*CD*A, 第二个可以是AE*F*

【讨论】:

    【解决方案3】:

    您需要使用的算法描述为here。如果您对该主题更感兴趣,我强烈建议您阅读 Michael Sipser 的 Introduction to the Theory of Computation

    对于您的特定 DFA,按照您得到此正则表达式的算法:

    [(010*1)*1(10*)110*1]*(010*1)*1(10)*110*
    

    【讨论】:

    • 您的正则表达式非常接近 DFA。通过将您的正则表达式绘制到 DFA,从 D 到 A 的转换消失了。
    • 抱歉,已修复。显然,这由计算机完成要好得多,因为它很容易出错。
    【解决方案4】:

    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*))*
    

    【讨论】:

    • 那里有轻微的错字...已修复
    • 我还假设E和B的自跃迁发生在0(图中缺少数字)
    • 您的基本正则表达式是正确的,但请再次检查。你能找到你的表达错误的原因吗?这是个好问题....(我不是反对者
    • 不,我不能。顺便说一句,您的正则表达式不接受 01110100110 这是此 DFA 的 vlid 字符串
    • @RedBaron 再次检查我的答案以及您的答案。还要检查您在评论中提出的两个问题。我对您的帖子发表了评论,因为您即将回答。我的 RE 处理你的字符串 A --0--E--1---F--1---A---1---B--0---B---1--C---0---B---0---B--1--C---1---D---0---D
    猜你喜欢
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 2015-12-21
    • 2017-02-09
    相关资源
    最近更新 更多