(简化)正则表达式匹配的复杂性

时间:2013-03-03 16:36:44

标签: regex algorithm time-complexity

我只是想知道这个正则表达式匹配问题的复杂性:给定一串小写字母和匹配规则,确定规则是否可以匹配整个字符串。该规则是一个简化的正则表达式,只包含较小的字母和/或'。' (期间)和/或'*'(星号)。句点可以匹配任何小写字母,其中星号可以匹配前面元素的零个或多个。

以下是一些例子:

  • isMatch(“aa”,“a”)为假
  • isMatch(“aa”,“aa”)是真的
  • isMatch(“aaa”,“aa”)为假
  • isMatch(“aa”,“a *”)为真
  • isMatch(“aa”,“。*”)为真
  • isMatch(“ab”,“。*”)为真
  • isMatch(“aab”,“c * a * b”)为真

据说这个问题可以在多项式时间内解决。我只是想知道如何。通过直觉,将“aaaaaaaaa”与像“。* a。*”这样的正则表达式匹配使得在与有限确定性机器匹配时难以确定状态转换。有什么意见吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用动态编程算法在多项式时间内解决此问题。我们的想法是回答以下形式的问题:

  

您可以使用正则表达式的最后n个字符匹配字符串的最后m个字符吗?

这个想法是使用递归算法,然后记住结果或使用动态编程来缓存结果。递归算法的工作原理如下:

  • 如果正则表达式为空,则只匹配空字符串。
  • 如果正则表达式的第二个字符不是*,则正则表达式匹配字符串iff字符串的第一个字符与正则表达式匹配,字符串的其余部分与正则表达式的其余部分匹配。
  • 如果正则表达式的第二个字符是*,则正则表达式匹配字符串iff以下之一为真:
    • 正则表达式的第一个字符与字符串的第一个字符匹配,同一个正则表达式与字符串的其余部分匹配。
    • 正则表达式的第一个字符与字符串的第一个字符匹配,删除了*'ed表达式的正则表达式与字符串的其余部分匹配。
    • 正则表达式的第一个字符与字符串的第一个字符不匹配,但删除*'ed表达式形成的正则表达式与字符串匹配。

这些情况中的每一个都进行递归调用,其中字符串或正则表达式更短并且O(1)除了递归调用之外还有效。由于只有Θ(mn)个可能的子问题(一个用于正则表达式的后缀和原始字符串的后缀的每个组合),因此使用memoization可以在Θ(mn)时间内解决此问题。

希望这有帮助!