Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 为什么使用NFA而不是DFA_Regex_Dfa_Computation Theory_Compiler Theory_Nfa - Fatal编程技术网

Regex 为什么使用NFA而不是DFA

Regex 为什么使用NFA而不是DFA,regex,dfa,computation-theory,compiler-theory,nfa,Regex,Dfa,Computation Theory,Compiler Theory,Nfa,我现在正在学习一些计算理论,正如所暗示的,这是非常理论化的 我可以很容易地将正则表达式转换为NFAs到DFAs,我可以理解这一点 但是,由于所有NFA都可以转换为DFA,并且(我很确定)UNIX中的grep命令使用regex来确定匹配字符串,那么最常用的有限自动机是DFA还是NFA 根据我的经验(不是很多),DFA在表示常规语言时通常更易于使用,而且也是确定性的,因此应始终选择DFA而不是NFA NFA分支到多个结果,需要递归函数,对我来说似乎更尴尬 我知道编译器是有限自动机的另一个实际用途 我

我现在正在学习一些计算理论,正如所暗示的,这是非常理论化的

我可以很容易地将正则表达式转换为NFAs到DFAs,我可以理解这一点

但是,由于所有NFA都可以转换为DFA,并且(我很确定)UNIX中的
grep
命令使用regex来确定匹配字符串,那么最常用的有限自动机是DFA还是NFA

根据我的经验(不是很多),DFA在表示常规语言时通常更易于使用,而且也是确定性的,因此应始终选择DFA而不是NFA

NFA分支到多个结果,需要递归函数,对我来说似乎更尴尬

我知道编译器是有限自动机的另一个实际用途

我的问题是。。。为什么要学习/使用两者。DFA对我来说似乎很好


谢谢你的回答

DFA通常更快,更具可扩展性。确定和最小化NFA有时成本高昂。因此,如果自动机只使用一次,则可以跳过它

NFA(Thompson NFA、Glushkov NFA、位并行NFA)的优点是:

  • 它们可以更简洁地表达
  • 他们可以记录子匹配(例如,用于正则表达式替换)
  • 它们可以动态转换为非最小化DFA
此外,通用编程语言中使用的正则表达式NFA(回溯NFA,例如Python、Perl、Java、.NET中的NFA,而不是grep中的NFA):

  • 甚至比上NFA更慢
  • 支持贪婪、非贪婪和占有模式
  • 但是可以使用lookaheads/lookbehinds
  • 并且可以使用反向引用(这些不能转换为DFA)

编译器几乎总是使用最小化的DFA进行词法分析。正则表达式搜索使用DFA或混合DFA/NFA(后者用于子匹配识别)。编程语言中使用的NFA是最强大的(就功能而言),但也是最慢的。

我认为将回归转换为NFA比DFA更简单。很难直接将回归转换为DFA。

可能需要补充的是,一些表示为DFA的正则语言会导致状态爆炸,例如,一些未绑定的匹配也会导致资源折衷。确定和最小化可能是时间和内存密集型的,因此只有当生成的自动机被大量使用时才有意义。第一条评论是指DFAs状态仅受O(2^n)的限制,其中n是NFA中的状态数,对吗