【问题标题】:Automata with kleene star带有克莱恩星的自动机
【发布时间】:2012-06-11 19:50:17
【问题描述】:

我正在学习自动机。你能帮我理解一下带 Kleene 闭包的自动机是如何工作的吗?假设我有字母 a、b、c,我需要找到以 Kleene 星号结尾的文本 - 比如 ab*bac - 它是如何工作的?

【问题讨论】:

    标签: algorithm kleene-star


    【解决方案1】:

    这个问题似乎更多的是关于自动机如何处理 Kleene 闭包,而不是 Kleene 闭包的含义。

    使用简单的正则表达式,例如abc,设计一个自动机来识别它是非常简单的。每个状态基本上都会告诉您到目前为止您在表达式中的位置。状态 0 意味着它还没有看到任何东西。状态 1 表示已看到 a。状态 2 表示已看到 ab。等等。

    Kleene 闭包的困难在于像ab*bc 这样的模式会引入歧义。一旦自动机看到a,然后面对b,它不知道bb*的一部分还是跟在它后面的文字b,它不会在它读取更多符号之前不知道——也许更多。

    简单的答案是自动机只是有一个状态,字面意思是它还不知道选择了哪条路径。

    在简单的情况下,您可以直接构建此自动机。在一般情况下,您通常会构建一种称为非确定性有限自动机的东西。您可以模拟 NDFA,或者 - 如果性能很关键 - 您可以应用一种将 NDFA 转换为确定性算法的算法。该算法本质上会为您生成所有模棱两可的状态。

    【讨论】:

    • ab*bc = ab+c。这实际上意味着“a,至少一个 b,c”。对不起,我没有发现任何模棱两可的地方。在自动机看到a 之后,它只是在寻找至少一个b,然后是c。一旦自动机处于状态ab+,它会在收到bs 时保持在那里。自动机只能走一条路。
    • 我了解 NFA 与 DFA,但是由于任何 NFA 都可以转换为 DFA,因此实际上只有一个路径可以接受字符串。
    • @VanDarg:是的,您可以以这种方式翻译模式并避免歧义。如果您尝试直接从原始正则表达式构建机器,您会不知道刚刚看到的bb* 还是b 的一部分。所以你需要一种状态来应对这种模糊性。
    【解决方案2】:

    Kleene 星号('*') 表示您可以根据需要(0 或更多)出现任意数量的字符。 a* 将匹配任意数量的 a。

    (ab)* 将匹配任意数量的字符串“ab”

    如果您尝试匹配表达式中的实际星号,您编写它的方式完全取决于您正在使用的正则表达式的语法。对于一般情况,反斜杠\ 用作转义字符:

    \* 将匹配一个星号。

    要在结尾识别模式,请使用连接:

    (a U b)*c* 将匹配任何结尾包含 0 个或多个 'c',前面有任意数量的 a's 或 b's 的字符串。

    对于以 Kleene 星号结尾的匹配文本,同样,字符串可以出现 0 次或多次:

    ab(c)* - 可能的匹配项:ab、abc、abcc、abccc 等。

    a(bc)* - 可能的匹配项:a、abc、abcbc、abcbcbc 等。

    【讨论】:

    • 我知道 kleene star 的作用,但可以说我知道如何构建自动机来识别以特定模式结尾的单词 - 识别以 kleene star 结尾的文本的自动机将如何工作?
    • 要在末尾识别模式,请使用连接:(a U b)*c* 将匹配任何末尾包含 0 个或多个 'c',前面有任意数量的 a's 或 b's 的字符串。
    • 再次阅读,我认为您对 kleene star 的定义不是我的意思(第二个答案是正确的)但我不确定我是否正确......
    • a* 后面应该跟任何字母 a,b,c
    • 我可以向您保证,我给 Kleene Star 的定义是正确的。见en.wikipedia.org/wiki/Kleene_star。此外,a* 的正则表达式后跟任何字母 a、b 或 c:a*(a U b U c)
    【解决方案3】:

    你的英语表达 ab*bac 应该是这样的:

    a 后跟 0 个或多个 b 后跟 bac

    strings that would evaluate as a match to the regular expression if used for search
    
    abac
    abbbbbbbbbbac
    abbac
    
    strings that would not match
    
    abaca //added extra literal
    bac //missing leading a
    

    如上一个答案所述,实际搜索 * 需要一个转义字符,该字符是特定于实现的,并且需要了解您选择的语言/库。

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 2018-03-22
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 2011-09-12
      • 2022-09-27
      • 2010-11-12
      • 1970-01-01
      相关资源
      最近更新 更多