nfa 与 dfa 的时间复杂度权衡

Posted

技术标签:

【中文标题】nfa 与 dfa 的时间复杂度权衡【英文标题】:time complexity trade offs of nfa vs dfa 【发布时间】:2011-06-02 14:42:23 【问题描述】:

我正在寻找关于哪个更好用以及在什么情况下在编译器中使用 nfa 或 dfa 的讨论。模拟 是什么?在编译器的什么情况下哪个更适合?

【问题讨论】:

我找到了其他人的答案.. 时空权衡目标:给定 reg。 exp.r 和输入stringx,判断x 是否在L(r) 方法#1:使用Thompson 构造从r 构建NFAN,然后运行之前的算法¡ 可以在O(|r|) 时间内构造NFA。 ¡ N 最多有 |r| 的两倍状态,每个状态最多有两个转换,所以转换表是 O(|r|) 空间。 ¡ 以前的算法在O(|r|×|x|) 时间内接受或拒绝x 方法 #2:使用 Thompson 的构造构建 NFAN fromr,然后使用子集构造构建 DFAD fromN;然后使用上次的 DFA 算法来接受/拒绝 x ¡ D 最多可以有 2k 个状态,其中 k = # 个状态 in N. ''Worst-case'' string (a |b)*a (a |b)(a |b)...(a |b):为什么? ¡ DFA接受算法接受或拒绝x inO(|x|) 总结:Automaton Build Run NFA O(|r|) O(|r|×|x|) DFA O(2|r|) O(|x|) 所以使用第一种方法(NFA ) 用于快速搜索短文本字符串(例如,emacs 重新搜索) 使用第二种方法 (DFA) 用于长文本字符串上的较长搜索(例如,Unix grep 对多个文件) ''Lazy'' DFA 方法在fly,遇到状态/输入对缓存转换 我知道从具有 $r$ 个状态的 NFA 构建的 DFA 中的状态数量可能高达 $2^r$,但我不明白从具有 $r$ 个状态的 NFA 成本 $O(2^r)$。在 DFA 的每个输入符号上添加边的成本如何?构造的 DFA 是 $O(vertices) = O(edges)$ 吗? 【参考方案1】: 从 NFA 构建 DFA 的时间为 O(2^m),其中 m 是节点数。 DFA 的运行时间为 O(n),其中 n 是输入字符串的长度。这是因为给定字符串只有 1 条通过 DFA 的路径。 NFA 的构建时间应该是 O(m),其中 m 是节点数 NFA 的运行时间为 O(m²n),因为它是不确定的,并且计算机必须检查字符串中当前字符的所有可能路径。 (假设没有前瞻,它不知道下一个字符会是什么,所以它会陷入死胡同)

这些数字可能会给你一个简要的想法

【讨论】:

正如您所建议的那样,通过回溯运行 NFA 在最坏的情况下将花费 O(2^n)。幸运的是,有一些更智能的算法需要 O(mn) 时间,尽管它们不支持反向引用。 (一种实现是 Google 的 re2。)

以上是关于nfa 与 dfa 的时间复杂度权衡的主要内容,如果未能解决你的问题,请参考以下文章

NFA/DFA算法

DFA 与 NFA 引擎:它们的功能和限制有何不同?

NFA 到 DFA 转换的简明描述?

C语言实现NFA转DFA

形式语言与自动机NFA

正规式与正规集,DFA与NFA