【问题标题】:How do I find the language from a regular expression?如何从正则表达式中找到语言?
【发布时间】:2011-11-29 15:33:24
【问题描述】:

我如何在字母表 {a, b} 上找到以下正则表达式的语言?

aUb*
(ab*Uc)
ab*Ubc*
a*bc*Uac

编辑:在我疯狂地投票之前,如果有人能向我展示解决这些问题的步骤,而不仅仅是解决方案,我将不胜感激。也许甚至可以带我完成一个,这样我就可以自己做剩下的事情了。

谢谢!

【问题讨论】:

  • 你在说什么语言?
  • 你听说过正则表达式吗?
  • 您可以从基于给定字母的语言构建正则表达式。因此,例如基于 {a, b} 有一组给定的规则可以构建上面的每一行。
  • @prgram4fun,当字母表仅限于“a”和“b”时,为什么在某些正则表达式中使用“c”?
  • @MostyMostacho,是的,这基本上是正则表达式工作方式背后的数学原理。我理解这个问题的唯一原因是因为我现在也在上这门课:)(但这并不意味着我知道答案......)

标签: regex context-free-grammar regular-language formal-languages


【解决方案1】:

尽管 Mike 给出了生成由正则表达式表示的语言的语法,但您的作业要求语言本身。因为您正在处理正则表达式,所以您的答案必须是正则集。

回忆一下字母表上正则集的定义:

Let Σ be an alphabet. The class of regular sets over Σ is the smallest class
containing ∅, {λ}, and {a}, for all a ∈ Σ, and closed under union, concatenation,
and Kleene star.

现在回忆一下字母表上正则表达式的定义:

Let Σ be an alphabet. The class of regular expressions over Σ is the smallest
class containing ∅, λ, and a, for all a ∈ Σ, and closed under union, concat-
enation, and Kleene star.

因此,翻译应该简单明了。事实上,它包括在每个字母周围插入大括号!例如:

a ∪ b*  denotes {a} ∪ {b}*
ab* ∪ c denotes {a}{b}* ∪ {c}
...

如果您想用集合生成器表示法表达每个正则表达式的语言,您可以恢复到对正则集合的操作的定义。回忆:

Let A and B be regular sets. Then
   1  A ∪ B = {x : x ∈ A ∨ x ∈ B}
   2. AB    = {xy : x ∈ A ∧ y ∈ B}
   3. A*    = ∪[i = 0 -> ∞]A^i

通过替换常规集合操作的定义,可以将常规集合转换为集合构建器符号。为了避免引入嵌套的集合构建符号,我将相等与串联的定义结合使用来表达常规集合的串联。

{a} ∪ {b}*    = {w : w ∈ {a} ∨ w ∈ ∪[i = 0 -> ∞]{b}^i}
{a}{b}* ∪ {c} = {w : (w = xy ∧ (x ∈ {a} ∧ y ∈ ∪[i = 0 -> ∞]{b}^i)) ∨ w ∈ {c}}
...

您现在应该能够毫无困难地找到其余表达式所表示的语言。

【讨论】:

    【解决方案2】:

    编辑:简短回答,* 在几乎所有正则表达式/语法语法中都表示“零次或多次重复”,包括 perl5 和 RFC 5234。* 通常比串联和交替绑定更紧密。

    您说您想要一种超越字母表 (a, b) 的语言,但在您的表达式中包含 cU。我将假设你想要一个语言语法在字母表(a,b,c)上的形式像 BNF 给定一个正则表达式,其中U 是一个低优先级联合运算符,类似于 perl 中的|回复。

    在这种情况下,

    a|b*
    

    等价于BNF:

    L := a
       | <M>
    M := epsilon
       | b <M>
    

    * 运算符表示零或多个,因此M 中的第一个子句是基本情况,第二个子句是M 的递归使用,其中包括一个终端b

    L 只是单个终端 a 或非终端 M

    (ab*|c)
    
    L ::= a <M>
        | c
    M ::= epsilon
        | b <M>
    

    M 的推导方法同上,其余的不言自明。

    ab*|bc*
    
    L ::= a <M>
        | b <N>
    M ::= epsilon
        | b <M>
    N ::= epsilon
        | c <N>
    

    N的推导方式与上述M相同。

    a*bc*|ac
    

    大多数正则表达式语言中的* 绑定比串联更紧密,所以这与

    (a*b(c*))|(ac)
    

    归结为

    L ::= <M> b <N>
        | a c
    M ::= epsilon
        | a <M>
    N ::= epsilon
        | c <N>
    

    通常要将正则表达式转换为 BNF,您只需使用正则表达式中的邻接来表示 BNF 中的邻接,而正则表达式中的 U| 表示 BNF 中的 |

    如果你定义了一个非终结符&lt;X&gt; ::= x,那么你可以这样处理x*

    L ::= epsilon
        | <X> <L>
    

    使用相同的非终结符 &lt;X&gt; ::= x 然后您可以处理 x+

    L ::= <X>
        | <L> <X>
    

    这让您得到重复运算符*+,留下?x?简直就是

    L ::= epsilon
        | <X>
    

    【讨论】:

    • 好吧,起初有点难以理解,但我明白了。所以基本上 * 意味着你可以拥有无​​限量的那封信?因此,例如,最后一个正则表达式可能表示 0 或任意数量的 a,1 b、0 或任意数量的 C,或 ac。就像你说的,c 没有意义,因为它不是字母表的一部分。所以我假设这是教授的错误。谢谢!
    • @prgram4fun,是的,* 表示任意数字,+ 表示一或多个,? 表示零或一。所有这些都比串联更紧密,串联比联合更紧密。
    【解决方案3】:

    如果您知道星号、联合和串联的含义,这些应该很容易。第一个是工会b星。根据操作顺序,这意味着联合(b 星)。联合表示左侧语言中的任何内容或右侧语言中的任何内容。 a 表示由长度为一的字符串 a 组成的语言; b 星表示由任何字符串组成的语言,该字符串由零个或多个 b 符号组成,仅此而已。所以这种语言是{empty, a, b, bb, bbb, bbbb, ...}。在第二个中,ab* 表示由 a 后跟零个或多个 b 符号组成的所有字符串。先做星号,然后是连接,然后是联合,遵守给定的显式括号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 2013-11-18
      • 2015-08-20
      相关资源
      最近更新 更多