将 NFA 转换为正则表达式

2024-01-03

我在这个网站上发现了同样的问题,答案是描述如何将 NFA 转换为正则表达式的 PDF http://courses.engr.illinois.edu/cs373/sp2009/lectures/lect_08.pdf。但这是行不通的,因为该方法有一些条件:

  1. 存在从初始状态到所有其他状态的转换,并且没有 过渡到初始状态。
  2. 有一个接受状态,只有进入它的转换(并且没有传出) 过渡)。
  3. 接受状态与初始状态不同。
  4. 除了初始状态和接受状态外,所有其他状态都与所有其他状态相连 通过过渡状态。特别是,每个状态都有一个到自身的转换。

在我的示例中,开始状态只是进入下一个状态,而不是所有状态(例如 q0 进入 q1,但不进入 q2、q3),并且存在到开始状态的转换。

那么将 NFA 转换为正则表达式的最简单方法是什么?我没有给出 NFA 的例子,因为我没有具体的例子,这只是一个一般性的问题,因为我遇到过这种 DFA,其中起始状态并不与所有状态相关,并且是转换到启动状态。

我想要一个通用算法来转换这种 NFA。


答案是假设这些条件,因为任何 NFA 都可以修改以满足这些要求。

For any kind of NFA, you can add a new initial state q0 that has an epsilon-transition to the original initial state, and also using an additional transition symbol called ∅ (they call it empty set symbol, assumed to be a symbol which does not match any symbol from the original NFA) from it to any other states, then use this new state as the new initial state. Note that this does not change the language accepted by the original NFA. This would make your NFA satisfies the first condition.

For any kind of NFA, you can add a new acceptance state qa that has an epsilon-transition from all acceptance state in the original NFA. Then mark this as the only acceptance state. Note that this does not change the language accepted by the original NFA. This would make your NFA satisfies the second condition.

By the above construction, by setting q0 != qa, it satisfies the third condition.

在您提供的链接中,第四个条件是通过一个称为 ∅(空集符号)的特殊转换符号来解释的,原始 NFA 中的实际字母表无法匹配该符号。因此,您可以使用这个新符号添加从每个状态到任何其他状态的转换。请注意,这不会更改原始 NFA 接受的语言。

现在 NFA 已被修改以满足四个要求,您可以应用那里的算法将 NFA 转换为正则表达式,它将接受与原始 NFA 相同的语言。

编辑以回答进一步的问题:

To answer your question in the comment, consider the NFA with two states, qA and qB. qA is the initial state as well as the only acceptance state. We have a transition from qA to itself with symbol 0,1. We also have transition from qA to qB with symbol 1. Lastly we have transition from qB to qA with symbol 0.

可视化:



 0,1    
  |  1
->qA----->qB
  ^       |
  |-------|
     0
  

Step 2. When we normalize the NFA, just put the new init state (qinit) that points to qA, and put a new acceptance state (qacc) from qA.

Step 3. We want to remove qA. So qA is the qrip in the algorithm (in page 3). Now we need to consider every states that enters qA and every states that exits from qA. In this case, there are two states pointing to qA, that are qinit and qB. There are two states that are pointed to by qA, that are qB and qacc. By the algorithm, we replace the transitions qin->qrip->qout with a transition qin->qout, having the transition symbol Rdir+Rin(Rrip)*Rout, where:

  1. Rdir is the original transition from qin to qout
  2. Rin is the original transition from qin to qrip
  3. Rrip is the original loop at qrip
  4. Rout is the original transition from qrip to qout

So in this case we replace the transition qinit->qA->qB with qinit->qB with transition symbol (0+1)*1. Continuing this process, we will create in total 4 new transitions:

  1. qinit->qB: (0+1)*1
  2. qinit->qacc: (0+1)*
  3. qB->qB: 0(0+1)*1
  4. qB->qacc: 0(0+1)*

Then we can remove qA.

Step 4. We want to remove qB. Again, we identify the qin and qout. There is only one state coming to qB here, which is qinit, and there is only one state departing from qB, which is qacc. So we have:

  1. Rdir = (0+1)*
  2. Rin = (0+1)*1
  3. Rrip = 0(0+1)*1
  4. Rout = 0(0+1)*

So the new transition qinit->qacc will be:

Rdir+Rin(Rrip)*Rout

(0+1)* + (0+1)*1 (0(0+1)*1)* 0(0+1)*

And we can remove qB.

步骤 5. 由于原始 NFA 中的每个状态都已被删除,我们就完成了。所以最终的正则表达式如上所示。

请注意,最终的正则表达式可能不是最佳的(并且在大多数情况下它不会是最佳的),这是算法所期望的。一般来说,为 NFA(甚至 DFA)找到最短的正则表达式是非常困难的(尽管在这个例子中很容易看出第一个组件已经涵盖了所有可能的字符串)

为了完整起见,接受相同语言的最短正则表达式将是:

(0+1)*

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 NFA 转换为正则表达式 的相关文章

  • 正则表达式替换混合数字+字符串

    我想删除所有包含数字的单词 示例 LW23 London W98 String 从上面的字符串中我唯一想保留的是 London String 这可以用正则表达式来完成吗 我目前正在使用 Python 但 PHP 代码也很好 Thanks E
  • [Regex]::Replace() 和 -replace 有什么区别?

    我明白了之间的区别 Replace and replace 但是什么是 replace and Regex Replace 我测试了以下两个代码 但对我来说结果完全相同 我还提到了 PowerShell Cookbook O reilly
  • 在 Java 正则表达式中获取多个模式的重叠匹配

    我有同样的问题这个链接 https stackoverflow com questions 18751486 matching one string multiple times using regex in java 但有多种模式 我的正
  • Python re无限执行

    我正在尝试执行这段代码 import re pattern r w w s re compiled re compile pattern results re compiled search COPRO HORIZON 2000 HOR p
  • REGEXP_REPLACE - 仅当包含在 () 中时才从字符串中删除逗号

    我在 oracle 论坛网站找到了一个例子 输入字符串 a b c x y z a xx yy zz x WITH t AS SELECT a b c x y z a xx yy zz x col1 FROM dual SELECT t c
  • 什么是仅匹配空字符串的正则表达式?

    有很多关于正则表达式的帖子来匹配潜在地空字符串 但我找不到任何提供正则表达式的字符串only匹配一个空字符串 我知道 将匹配任何行的开头并且 将匹配任何行的结尾以及字符串的结尾 像这样 匹配的内容远不止空字符串 如 n foobar n n
  • 使用 posix shell 测试字符串中的正则表达式

    如何测试字符串是否与特定字符串匹配正则表达式与基本 无 bash 或任何其他 posix shell 脚本 在 if 语句中 您可以使用expr在 POSIX shell 中计算正则表达式的命令 s Abc expr s alpha 3 e
  • Python 非贪婪正则表达式

    我如何制作一个像这样的Python正则表达式 这样 给定 a b c d e 蟒蛇匹配 b 代替 b c d 我知道我可以使用 代替 但我正在寻找一种更通用的解决方案 使我的正则表达式更加干净 有没有办法告诉python 嘿 尽快匹配这个
  • Java 正则表达式 - 字母数字,最多一个连字符,句点或下划线,七个字符长

    我是 Java 正则表达式工具的新手 尽管它们潜力巨大 但我很难完成这项任务 我想编写一个正则表达式来验证遵循以下语法的输入字符串 小写字母和数字的任意组合 仅一个下划线 一个破折号或一个句号 无其他特殊字符 最小长度为 5 我想出了以下解
  • 将html数据解析成python列表进行操作

    我正在尝试读取 html 网站并提取其数据 例如 我想查看公司过去 5 年的 EPS 每股收益 基本上 我可以读入它 并且可以使用 BeautifulSoup 或 html2text 创建一个巨大的文本块 然后我想搜索该文件 我一直在使用
  • Golang 正则表达式在字符串之间替换

    我有一些可能采用以下形式的字符串 MYSTRING MYSTRING n MYSTRING n MYSTRING randomstringwithvariablelength n 我希望能够将其正则表达式为MYSTRING foo 基本上替
  • 扩展 RegExp 以获取文件扩展名

    我知道 已经有很多基于 RegExp 的解决方案 但是我找不到适合我需求的解决方案 我有以下函数来获取 URL 的各个部分 但我还需要文件扩展名 var getPathParts function url var m url match w
  • 从字体到跨度(大小和颜色)和背面的正则表达式(VB.NET)

    我正在寻找一个正则表达式 可以将我的字体标签 仅具有大小和颜色属性 转换为具有相关内联CSS的span标签 如果有帮助的话 这将在 VB NET 中完成 我还需要一个正则表达式来实现相反的效果 下面详细说明的是我正在寻找的转换示例 font
  • sed 错误“未终止的 's' 命令”故障排除

    我正在构建一个script https stackoverflow com questions 4036832 replacing a specific term in an xml file其中 它将用文件夹路径替换 XML 文件中的模式
  • 如何用正则表达式替换多个匹配/组?

    通常我们会编写以下内容来替换一场比赛 namesRegex re compile r is life re I replaced namesRegex sub r butter There is no life in the void pr
  • JavaScript 中的实时摩尔斯电码转换器

    在看到谷歌关于莫尔斯电码 gmail 的愚人节笑话后 我想我应该尝试用 javascript 创建一个实时莫尔斯电码转换器 我正在使用正则表达式和替换将莫尔斯电码更改为字符 例如 replace g a replace g r 我遇到的问题
  • 正则表达式库基准

    我最近一直想知道正则表达式实现的性能 并且很难想出很多有用的信息 它很容易对浏览器 javascript 正则表达式性能进行基准测试 网上有很多工具 Chrome 和 Opera 中的 javascript 正则表达式实现几乎摧毁了所有其他
  • 如何使正则表达式匹配不区分大小写?

    我有以下正则表达式加拿大的邮政编码 http en wikipedia org wiki Postal codes in Canada ABCEGHJKLMNPRSTVXY 1 d 1 A Z 1 d 1 A Z 1 d 1 它工作正常 但
  • Java:正则表达式排除空值

    在问题中here https stackoverflow com questions 51359056 java regexp for a separated group of digits 我得到了正则表达式来匹配 1 到 99 之间的一
  • 反向引用在 PHP 中不起作用

    最近我一直在研究 更多的是在实践中说实话 正则表达式 我注意到他的力量 我提出的这个要求 link https stackoverflow com questions 30380397 take the text up to a speci

随机推荐