【问题标题】:Does an algorithm exist which can determine whether one regular language matches any input another regular language matches?是否存在一种算法可以确定一种常规语言是否匹配另一种常规语言匹配的任何输入?
【发布时间】:2011-04-07 12:14:03
【问题描述】:

假设我们有正则表达式:

  • 你好 W.*rld
  • 你好世界
  • .* 世界
  • .* W.*

我想尽量减少匹配任意输入所需的正则表达式的数量。

为此,我需要查找一个正则表达式是否与另一个表达式匹配的任何输入相匹配。这可能吗?

比利3

【问题讨论】:

  • @skaffman:我认为正则语言标签是合适的,因为正则表达式描述了一种常规语言——这只是“在纸上”表示它的一种简单方式。但问题是w.r.t。计算机科学与正则语言的关系比正则表达式更多。
  • 呃,标题与描述不符?
  • 我不确定是否符合“算法”的条件,但使用“.*”可以将任意输入与一个正则表达式匹配;我怀疑它可以最小化到小于 1。:-)
  • @Jerry: 嗯,这些只是例子 :) 在实际情况中它们更复杂。 @maxschlepzig:我稍微修改了描述。

标签: regex computer-science theory


【解决方案1】:

任何正则表达式都可以链接到 DFA - 您可以最小化 DFA,并且由于最小形式是唯一的,您可以决定两个表达式是否等价。 Dani Cricco 指出了 Hopcroft O(n log n) 算法。 Hopcroft 和 Craft 还有另一种改进的算法,用于在 O(n) 中测试两个 DFA 的等价性。

关于这个问题的一个很好的调查和一个有趣的方法,我推荐来自 arXiv 的论文Testing the Equivalence of Regular Languages

稍后编辑:如果您对正则表达式的包含而不是等价感兴趣,我遇到了一篇可能感兴趣的论文:Inclusion Problem for Regular Expressions - 我只是略读了一下,但它似乎包含多项式时间算法解决问题。

【讨论】:

  • 嗯.. 很有趣。一个问题是.*Hello World 显然不等价,尽管.* 可以匹配任何Hello World 可以匹配的东西。
  • 我不确定“匹配”对您的含义 - 似乎您不想测试等价性而是包含性。你的问题能更准确一点吗?
  • 我的困难是我不知道如何准确地描述我正在寻找的东西——我很抱歉这里的跑题。我稍微修改了这个问题——从维基百科关于集合论包含的描述来看,确实符合我的需要。
  • @Billy:我认为我刚刚添加的链接论文正是您要找的。​​span>
  • @Billy ONeal:如果你对一个近似值(你可能是)没意见,那么这个答案中的最后一篇论文可能对你有好处。
【解决方案2】:

是的。

两种正则语言的等价问题是可判定的。

算法示意图:

  • 最小化两个 DFA
  • 检查它们是否同构

【讨论】:

  • 图同构在多项式时间内是不可解的,所以我看不出这有什么帮助。
  • @Billy:我猜你的回答是,这是一个理论上可以解决的问题,但实际上无法解决。
  • @szbalint:好吧,“理论上”,我可以将所有可能的输入字符串设置为语言,看看它们是否匹配相同的东西。如果在合理的消费类硬件上无法解决,那就没有意义了。
  • @Billy ONeal:图同构与它有什么关系?并且不要抨击理论上的cs。可判定的结果具有实际意义。例如。两种上下文无关语言的等价问题是不可判定的。
  • 我不是在“抨击理论 CS”——但我认为从我的问题中可以明显看出,证明问题仅仅是可判定的对于答案来说并不是那么有用。
【解决方案3】:

当然!正则表达式可以表示为 FSM(有限状态机),从技术上讲,有无数个 FSM 可以识别相同的字符串。

同构是描述两个 FSM 是否等价的名称。有几种算法可以最小化 FSM。例如,Hopcroft minimization algorithm 可以在一个 n 状态自动机上以 O(n log n) 最小化两个 FSM。

【讨论】:

  • @Dani:maxschlepzig 的回答也有同样的问题。同构属于 NP 类。
  • @Billy ONeal:首先,(图)同构在 NP 中(这是真的),但被认为不是 NP 完全的,虽然不在 P 中。但是,我们正在谈论 DFA 同构,这是一个完全不同的东西。
  • @Billy:DFA 同构在 P 类中
  • @Billy DFA 同构更简单。你只有一个起点
  • @Billy ONeal:基本上,DFA 和图之间的最大区别在于 DFA 被标记,因此您首先知道要匹配什么(初始/终止状态,具有相同的边信件)。此外,有些 DFA 是同构的(我们谈论的是由从状态开始的后缀等价定义的同构,还有其他可能的同构定义),但它们的图形表示不是。
【解决方案4】:

这个问题称为正则表达式的“包含”或“包含”,因为您要求的是一个正则表达式匹配的单词集是否包含(或包含)另一个正则表达式匹配的单词集。平等是一个不同的问题,通常意味着两个正则表达式是否匹配完全相同的单词,即它们在功能上是等价的。例如“a*”包括“aa*”,但它们不相等。

所有已知的包含正则表达式的算法都是最坏的情况,在正则表达式的大小上花费时间指数。但是标准算法是这样的:

输入 r1 和 r2 如果 r1 包含 r2,则输出 Yes

  1. 创建 DFA(r1) 和 DFA(r2)
  2. 创建 Neg(DFA(r1))(与 r1 不匹配的单词完全匹配)
  3. 创建 Neg(DFA(r1))x DFA(r2)(与 Neg(DFA(r1)) 匹配的单词完全匹配 DFA(r2))
  4. 检查3.中制作的自动机不匹配任何单词

这行得通,因为您要检查的是没有与 r2 匹配但与 r1 不匹配的单词。

【讨论】:

    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 2014-09-21
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多