优化巨大的“OR”模式

时间:2013-05-01 14:32:35

标签: regex algorithm optimization tree logic

我有一个" OR"模式如下例: (X Y Z)| (X Y A B)| (X A K)| (M A J K)| (M A B)| (M Z)。 我的问题是,我真正问题的OR操作数很多,导致大量内存消耗问题。

然而,形成图案本身的条目很少(X,Y,Z,A,B,K,M和J)。 因此,将该模式转换(优化)为这样的模式: (X((Y(Z |(A B)))|(A K)))| (M((A((J K)| B))| Z)) ,很可能会解决我的记忆问题。

我需要一个算法来获取输入模式(可能是字符串)和 产生优化的(也可能是字符串)。

3 个答案:

答案 0 :(得分:3)

请注意(XA)|(XB) = X(A|B)。根据这个属性,我可以建议以下贪婪的解决方案:

P 为表达式, X P P = (XR1)|(XR2)|...|(XRn)|Q中最常见的条目。然后,从括号中取出 X P 可以表示为P = XR | Q,其中R = (R1|R2|...|Rn)。完成此操作后,递归解决 R Q 的问题。

答案 1 :(得分:1)

通常,布尔表达式的简化是NP难的(例如,参见Is minimization of boolean expressions NP-Complete?)。

如果你最多有8个文字或非否定变量,那么最多可能有256个min-terms,这不是一个很大的数字,所以我想你有比8更多的变量。考虑使用{ {3}}简化表达而不是某些特殊方法。或者,如果变量的数量很大但不是很大(例如,小于64的一些小的倍数),则将每个min-term表示为位掩码,并在读取它们时将OR表示在一起,而不是象征性地进行评估。

答案 2 :(得分:0)

通过使用regex标签,我推断出要优化的表达式是正则表达式,而不是布尔表达式。

正则表达式可以很容易地简化为DFA(状态机),尽管状态数可能是正则表达式大小的指数。获得DFA后,您可以使用minimizing DFAs之一的众所周知的算法;在O(n log n)中执行此操作并不困难,其中n是状态数。

一个好的正则表达式库应该能够为你做这一切,但很多人都没有。您可能需要查看Ragel

如果正则表达式的DFA实际上比正则表达式大得多,这很少但不完全未知,您可能会发现上述过程会破坏内存。因此,许多正则表达式库不执行完整的DFA减少;相反,它们只减少到NFA,然后懒惰地执行powerset构造,缓存结果。这应该以增加扫描时间为代价来避免内存问题。

显示指数爆炸的正则表达式示例:

A(A|B)(A|B)(A|B)(A|B)(A|B)(A|B)

相应的DFA必须至少有32个状态(即2 5 ,其中5(A|B)的重复次数。