【问题标题】:Calculate if two infinite regex solution sets don't intersect计算两个无限正则表达式解决方案集是否不相交
【发布时间】:2011-10-11 21:34:04
【问题描述】:

计算两个任意正则表达式是否有任何重叠的解决方案(假设有可能)。

例如,这两个正则表达式可以通过蛮力证明没有交集,因为这两个解集是可计算的,因为它是有限的。

^1(11){0,1000}$ ∩     ^(11){0,1000}$        = {}
{1,111, ..., ..111} ∩ {11,1111, ..., ...11} = {}
{}                                          = {}

但是将{0,1000} 替换为* 消除了暴力解决方案的可能性,因此必须创建更智能的算法。

^1(11)*$ ∩ ^(11)*$ = {}
{1,^1(11)*$} ∩ {^(11)*$} = {}
{1,^1(11)*$} ∩ {11,^11(11)*$} = {}
{1,111,^111(11)*$} ∩ {11,^(11)*$} = {}
.....

在另一个similar question 一个answer 是计算交集正则表达式。那有可能吗?如果是这样,如何编写算法来做这样的事情?

我认为这个问题可能是halting problem 的域。

编辑:

我已使用公认的解决方案为示例问题创建 DFA。很容易看出如何在 M_3 的状态图上使用 BFS 或 DFS 来确定来自 M_3 的最终状态是否可达。

【问题讨论】:

  • 链接的问题有一些很好的答案。为什么在您看来这不是重复的? IOW,请激发这种“改革”的合法性?
  • 链接的问题产生了许多理论答案。我喜欢提出的这个问题,因为它明确地邀请了一个实际的解决方案。它让我想起了我今年早些时候提出的一个问题,其动机仅仅是为了有效地评估 ~100 个正则表达式与 ~10^9 个字符串。仅当用于计算关系的逻辑有效时,才在这种情况下“预先计算”正则表达式“关系”(正交性、>、

标签: regex algorithm language-agnostic set intersection


【解决方案1】:

它不在停机问题的范围内;判断正则语言的交集是否为空可以解决如下:

  1. 为第一语言构造一个 DFA M1。
  2. 为第二语言构造一个 DFA M2。 提示:Kleene 定理和幂集机器构造
  3. 为 M1 与 M2 相交构造一个 DFA M3。 提示:笛卡尔积机器构造
  4. 确定 L(M3) 是否为空。 提示:如果 M3 有 n 个状态,并且 M3 不接受任何长度不大于 n 的字符串,那么 L(M3) 为空……为什么?

这些事情中的每一件事都可以通过算法完成和/或检查。此外,自然地,一旦 DFA 识别出您的语言的交集,您就可以构建一个正则表达式来匹配该语言。如果你从一个正则表达式开始,你可以制作一个 DFA。这绝对是可计算的。

编辑:

因此,要构建笛卡尔积机器,您需要两个 DFA。令 M1 = (E, q0, Q1, A1, f1) 和 M2 = (E, q0', Q2, A2, f2)。在这两种情况下,E 是输入字母表,q0 是起始状态,Q 是所有状态的集合,A 是接受状态的集合,f 是转移函数。构造 M3 在哪里...

  1. E3 = E
  2. Q3 = Q1 x Q2(有序对)
  3. q0'' = (q0, q0')
  4. A3 = {(x, y) | A1 中的 x 和 A2 中的 y}
  5. f3(s, (x, y)) = (f1(s, x), f2(s, y))

如果我没有犯任何错误,L(M3) = L(M1) 与 L(M2) 相交。整洁吧?

【讨论】:

  • 注意:这是假设 true 正则表达式(在现实生活中,几乎没有正则表达式引擎由于前瞻、后向引用、反向引用以及其他原因而受到限制出于务实的原因添加)
  • @sehe:请注意:向前看/向后看不要增加力量。他们仍然在 true 正则表达式的领域:)
  • 您认为您可以提供更多有关Cartesian Product Machine construction 的详细信息吗?或者甚至展示如何使用我给出的示例来完成它?我只能在谷歌图书上找到一个partial book
  • ... 这可以重复,只要结果字符串比 n 长,所以最终会产生一个长度
  • ... 我现在看到的基本上就是你已经在说的了 :) 正如你所说,DFS/BFS 需要避免以前访问过的状态以避免无限循环。
【解决方案2】:

我创建了 Patrick87 的PHP implementation 答案。除了通过笛卡尔积机器实现交集之外,我还实现了一种替代算法,用于使用De Morgan 查找 DFA 的交集。

Intersection( DFA_1, DFA_2 ) === ! UNION( ! DFA_1, ! DFA_2 )

* ! is defined as negation

这对于 DFA 非常有效,因为对完全定义的 DFA(定义了所有可能的转换状态的 DFA)的否定只是将所有非最终状态添加到最终状态集中并从最终状态中删除所有当前最终状态设置(非最终->最终,最终->非->最终)。 DFA 的并集可以很容易地完成,方法是将它们变成 NFA,然后创建一个新的起始节点,该节点通过 lambda 变换将合并后的 DFA 的旧起始节点连接起来。

除了解决交集问题,library I created 还能够将 NFA 确定为 DFA,并将 Regex 转换为 NFA。

编辑:

我创建了一个webapp,它允许使用我从这个问题(和其他问题)中学到的知识对正则表达式语言进行这种转换。

【讨论】:

    猜你喜欢
    • 2018-11-21
    • 1970-01-01
    • 2017-07-17
    • 2010-10-25
    • 1970-01-01
    • 2013-09-29
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多