【发布时间】:2008-08-22 03:02:34
【问题描述】:
我在任何地方都没有得到答案。正则表达式匹配和替换的运行时复杂度是多少?
编辑:我在 python 中工作。但想大致了解最流行的语言/工具(java、perl、sed)。
【问题讨论】:
我在任何地方都没有得到答案。正则表达式匹配和替换的运行时复杂度是多少?
编辑:我在 python 中工作。但想大致了解最流行的语言/工具(java、perl、sed)。
【问题讨论】:
从纯粹的理论立场:
我熟悉的实现是构建一个确定性有限自动机来识别正则表达式。这是在 O(2^m) 中完成的,m 是正则表达式的大小,使用标准算法。一旦构建完成,通过它运行一个字符串在字符串长度上是线性的 - O(n),n 是字符串长度。在字符串中找到的匹配项的替换应该是常数时间。
所以总的来说,我想 O(2^m + n)。
【讨论】:
其他可能感兴趣的理论信息。
为清楚起见,假设正则表达式的标准定义
http://en.wikipedia.org/wiki/Regular_language
来自形式语言理论。实际上,这意味着唯一的建筑 材料是字母符号,连接运算符,交替和 Kleene 闭包,以及单位和零常数(出现在 群论原因)。一般来说,不要超载这个术语是个好主意 尽管脚本语言的日常实践导致 模棱两可。
有一个 NFA 结构可以解决正则的匹配问题 表达式 r 和输入文本 t 在 O(|r| |t|) 时间和 O(|r|) 空间中,其中 |-|是长度函数。 Myers进一步改进了这个算法
http://doi.acm.org/10.1145/128749.128755
通过使用自动机节点列表和四俄罗斯人范式,时间和空间复杂度 O(|r| |t| / log |t|)。这个范式似乎是以四个俄罗斯人的名字命名的,他们写了一篇开创性的论文 在线的。然而,范式在这些计算生物学中得到了说明 讲义
http://lyle.smu.edu/~saad/courses/cse8354/lectures/lecture5.pdf
我觉得用数字命名范式很有趣 作者的国籍而不是他们的姓氏。
添加反向引用的正则表达式的匹配问题是 NP-complete,由 Aho 证明
http://portal.acm.org/citation.cfm?id=114877
通过减少顶点覆盖问题,这是一个经典的 NP 完全问题。
为了确定性地匹配正则表达式和反向引用,我们可以 使用回溯(与 Perl 正则表达式引擎不同)来跟踪 可以分配给变量的输入文本 t 的可能子词 河。只有 O(|t|^2) 个子词可以分配给任何一个变量 在河如果r中有n个变量,那么有O(|t|^2n)个可能 作业。一旦将子字符串分配给变量是固定的, 问题简化为普通的正则表达式匹配。因此 匹配正则表达式与反向引用的最坏情况复杂度是 O(|t|^2n)。
但是请注意,带有反向引用的正则表达式还没有 功能齐全的正则表达式。
例如,将“无关”符号与其他符号区分开来 运营商。有几种多项式算法决定一组 模式匹配输入文本。比如库切罗夫和鲁西诺维奇
http://dx.doi.org/10.1007/3-540-60044-2_46
将模式定义为一个单词 w_1@w_2@...@w_n 其中每个 w_i 是一个单词(不是正则表达式),而“@”是一个不包含在任何一个中的可变长度“无关”符号w_i。他们推导出一个 O((|t| + |P|) log |P|) 算法,用于将一组模式 P 与输入文本 t 进行匹配,其中 |t|是文本的长度,|P|是P中所有单词的长度。
了解这些复杂性度量如何组合以及什么是有趣的 是正则表达式匹配问题的复杂度度量 反向引用、“不关心”和其他有趣的实用功能 正则表达式。
唉,我对 Python 只字未提... :)
【讨论】:
取决于您通过正则表达式定义的内容。如果允许连接、替代和 Kleene-star 运算符,则时间实际上可以是 O(m*n+m),其中 m 是正则表达式的大小,n 是字符串的长度。你可以通过构造一个 NFA(在 m 中是线性的),然后通过维护你所处的状态集并为每个输入字母更新它(在 O(m) 中)来模拟它。
使正则表达式解析变得困难的事情:
O(m^2+n)
O(2^m),可能是 PSPACE-complete)。但是应该仍然可以使用O(n^2*m) 之类的动态算法来解决
请注意,通过具体实施,事情可能会变得更好或更糟。根据经验,简单的特征应该足够快,并且明确的(例如,不像a*a*)正则表达式更好。
【讨论】:
深入研究theprise的答案,对于自动机的构造,O(2^m) 是最坏的情况,尽管它实际上取决于正则表达式的形式(对于一个匹配单词的非常简单的表达式,它是在 O(m) 中,例如使用 Knuth-Morris-Pratt algorithm)。
【讨论】:
取决于实施。什么语言/图书馆/课程?可能有一个最好的情况,但它会非常具体到实现中的功能数量。
【讨论】:
您可以通过构建非确定性有限自动机而不是 DFA 来以空间换取速度。这可以在线性时间内遍历。当然,在最坏的情况下,这可能需要 O(2^m) 空间。我希望这种权衡是值得的。
【讨论】:
如果您在匹配和替换之后,这意味着分组和反向引用。
这是一个 perl 示例,其中可以使用分组和反向引用来解决 NP 完全问题: http://perl.plover.com/NPC/NPC-3SAT.html
这(加上一些其他的理论花絮)意味着使用正则表达式进行匹配和替换是 NP 完全的。
请注意,这与正则表达式的正式定义不同 - 它没有分组的概念 - 并且在多项式时间内匹配,如其他答案所述。
【讨论】: