关于正则表达式:将规则表达式转换为DFA

Convert a regulation expression to DFA

一个多小时以来,我一直在尝试不同的方法来解决此问题,并且感到非常沮丧。

问题是:通过Sigma = {0,1}给出以下每种语言的正则表达式和DFA。

a)。 {w a ?? ?£ * | w包含偶数0或奇数1s}

如果有人可以提供提示或让我开始弄清楚这一点,将不胜感激!

我知道这是与此DFA相似的内容,但这是针对

的内容

{w a ??? ?£ * | w包含偶数0或正好是两个1}

所以有点不同,但我无法弄清楚。

enter


您可以看到以下内容:您必须记住两件事:

  • 0的数目是偶数还是奇数;和
  • 1的数目是偶数还是奇数。
  • 现在,如果我们用e表示偶数,而用o表示奇数,则考虑四个状态:ee(均为偶数),eo(偶数为0且奇数为1s),oe和oo。

    现在,当我们读取零(0)时,我们只需交换第一个状态令牌,所以这意味着我们引入了以下转换:

  • ee-0-> oe;
  • eo-0-> oo;
  • oe-0-> ee;和
  • oo-0-> eo。
  • 与(1)相同:

  • ee-1-> eo;
  • eo-1-> ee;
  • oe-1-> oo;和
  • oo-1-> oe。
  • 现在,我们只需要确定初始状态和接受状态即可。初始状态为ee,因为那时我们没有考虑零和零。

    此外,可以通过以下条件确定接受状态:

    w contains an even number of 0s or an odd number of 1s

    因此,表示接受状态为ee,eo和oo。此DFA的图形如下所示:

    dfa

    存在一种将DFA转换为等效正则表达式的算法,如此处所述。

    您可以通过将问题分解为两个更简单的问题来构造正则表达式:

    • 一个正则表达式,用于检查0的数量是否为偶数;和
    • 一个正则表达式,用于检查1的数目是否为奇数。

    首先,您可以使用正则表达式:

    1
    (1*01*0)*1*

    确实:您首先有一个组(1*01*0)。该组确保存在两个零,并且1可以出现在两个零之间。我们允许任意数量的重复,因为该数量始终保持偶数。正则表达式以1*结尾,因为字符串中仍有可能存在其他附加内容。

    第二个问题可以用正则表达式解决:

    1
    0*1(0*10*1)*0*

    解决方案大致相同。方括号之间的表达式:(0*10*1)确保它们均匀出现。通过在前面添加1,我们确保1的数量是奇数。

    然后解决该问题的正则表达式为:

    1
    (1*01*0)*1*|0*1(0*10*1)*0*

    因为"竖线"(|)表示"或"。


    考虑一下您可能处于的可能状态。

    • 一个数字包含0的偶数或0的奇数。 (2种可能的状态)
    • 一个数字包含1的偶数或1的奇数。 (2种可能的状态)

    现在让我们看看您的语言接受哪些组合:

  • 偶数0,偶数1:接受
  • 偶数0,奇数1:接受
  • 奇数0,偶数1:拒绝
  • 奇数0,奇数1:接受
  • 因此,您的DFA将需要4个状态,其中3个为接受状态,而1个为拒绝状态。每个状态都会有2个转换,导致一个不同的状态。由于空字符串的偶数个数为0,偶数个数为1,因此第一个状态将是初始状态。

    为使其成为正则表达式:考虑如何匹配偶数0,然后匹配奇数1。语言只是这两者的结合。

    或者,如Willem所建议的,您可以使用算法将任何NFA转换为正则表达式。它具有非常通用的优点,但是它也更具技术性。无论哪种方式,它都应导致等效的正则表达式。

    偶数为0的数字是什么样的?它可以以任何1开头,但是当我们找到0时,最好再找到一个!两者之间可以有任意数量的1,但我们只关心0。因此,我们得出以下正则表达式:

    1
    1*(01*01*)*

    您应该能够应用类似的逻辑以匹配1的奇数。最后,对两个表达式进行"或"运算以获取所请求的正则表达式。