微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

来自一组字符串的最小 DFA/正则表达式

如何解决来自一组字符串的最小 DFA/正则表达式

我正在寻找一种算法,它产生最小的 DFA,它匹配给定的有限具体字符串集中的任何字符串,仅此而已。 (最小的因为最少的终结符。)

示例:

  • a,b -> a|b
  • a,ab -> a(|b)
  • ab,ac -> a(b|c)
  • aaabbabb -> (a|b)(a|b)
  • xxaxbxcxacxbc -> x(|ab)(|c)

我尝试了一种简单的算法,该算法会重复提取前缀/后缀,但无法处理最后一种情况,并且不会产生最小的结果。

我确定这是一个常见问题,但我一直无法找到合适的术语。对不当的术语和临时符号表示歉意。

解决方法

最小 DFA 非常简单:

  1. 创建一个 NFA,该语言中的每个字符串都有一个分支
  2. 确定 NFA 以获得 DFA
  3. 最小化 DFA

这些步骤中的每一个都易于理解和自动化;第 2 步和第 3 步有已知的算法,第 1 步也应该很容易。

这不是一个特别有效的算法,但它可以作为一个有用的起点。为了提高性能,您需要尝试直接构建一些 DFA,然后将其最小化;也许将 Myhill-Nerode 定理作为一种构造来运行可以在这里工作。但这是性能,而不是正确性……对于小型 DFA,仅按上述方式运行不会有任何问题。

我认为最小正则表达式是一个更难的问题;您可以使用 Arden 引理作为起点,为使用上述技术生成的 DFA 语言获取一些正则表达式。然后,在绝对最坏的情况下,您可以检查是否有任何长度较短的有效正则表达式准确地给出了您的语言。请注意,因为您的语言是有限的,并且您想要完全匹配它,所以您的正则表达式中不会包含 Kleene 星,所以这可能不像听起来那么可怕;剩下的唯一操作是串联和联合。这可能是可行的,如果不是非常有效的话。很多这些选项可能很容易排除。例如,您知道,您至少需要与集合中最长字符串一样多的串联,这样就可以轻松设置下限;您可能会发现更严格的界限。来自 Arden 引理的正则表达式应该给你一个很好的上限。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。