【发布时间】:2014-03-13 00:08:08
【问题描述】:
我需要一些帮助来了解如何使用以下内容来制作将用于生成 epsilon NFA 的正则表达式。
字母是 {0,1}
语言是:所有以101开始,以01010结束的字符串的集合。
有效的字符串是:
- 101010
- 10101010
- 101110101
- 1011101010
我更关心理解如何制作正则表达式。
【问题讨论】:
我需要一些帮助来了解如何使用以下内容来制作将用于生成 epsilon NFA 的正则表达式。
字母是 {0,1}
语言是:所有以101开始,以01010结束的字符串的集合。
有效的字符串是:
我更关心理解如何制作正则表达式。
【问题讨论】:
你需要的正则表达式很简单:
101010|101(0|1)*01010 (theoretical)
或
^101010|101[01]*01010$ (used in most programming languages)
这意味着:
或
以下非确定性自动机应该可以工作:
【讨论】:
(0+1)* 部分?为什么不[01]*?
|,我使用的是很久以前在编译器课程中学到的语法,我相信这是正式定义,其中@ 987654328@ 或| 表示联合。当然,正如您所指出的,在大多数编程语言中,这将表示为[01]*。检查en.wikipedia.org/wiki/Regular_expression#Formal_language_theory
^ 和$ 锚定它,因为当前查询将匹配54321010101012345
q_0 和一组最终状态(在此示例中,只有一个状态:<q_8>)。当他提到 alphabet、language、automata 等时,我认为 OP 是在谈论 theoretical 正则表达式。
要了解您要查找的内容,使用交集运算符(以下用 & 表示)会很有帮助。它不属于理性表达的核心集合,但它保留了理性——换句话说,你可以使用它,并且总能找到一种方法来表达没有它的同一种语言。
使用Vcsn,我在文本模式下得到这个:
In [1]: import vcsn
In [2]: vcsn.B.expression('(101[01]*)&([01]*01010)').derived_term().expression()
Out[2]: 101010+101(0+1)*01010
这是在图形模式下,显示使用derived_term 计算的中间自动机(其中包括有关每个状态的“含义”的详细信息,因此随后调用strip 以获得更易于阅读的内容):
【讨论】:
我会建议一种同时包含基本情况和一般情况的模式。您需要覆盖 101010 的基本情况,其中两个模式重叠(以“101”开头,以“01010”结束,第一个模式的最后两位数字是第二个模式的前两位数字。然后你可以涵盖 Oscar 给出的“101”、任何 0 或 1、“01010”的一般情况。
所以完整的模式是:
^(101010|(101[01]*01010))$
【讨论】: