计算两个任意正则表达式是否有任何重叠解(假设它是可能的)。
例如,这两个正则表达式可以通过强力显示没有交叉点,因为这两个解决方案集是可计算的,因为它是有限的。
^1(11){0,1000}$ ∩ ^(11){0,1000}$ = {}
{1,111, ..., ..111} ∩ {11,1111, ..., ...11} = {}
{} = {}
但是将{0,1000}
替换为*
可以消除暴力解决方案的可能性,因此必须创建更智能的算法。
^1(11)*$ ∩ ^(11)*$ = {}
{1,^1(11)*$} ∩ {^(11)*$} = {}
{1,^1(11)*$} ∩ {11,^11(11)*$} = {}
{1,111,^111(11)*$} ∩ {11,^(11)*$} = {}
.....
在另一个similar question answer中计算交集正则表达式。这可能吗?如果是这样,怎么会写一个算法来做这样的事情呢?
我认为这个问题可能是halting problem的域名。
编辑:
我使用了已接受的解决方案为示例问题创建了DFA。很容易看出如何在M_3
的状态图上使用BFS或DFS来确定M_3
的最终状态是否可以到达。
答案 0 :(得分:17)
这不是停止问题的范畴;判断常规语言的交集是否为空可以解决如下:
每个事情都可以通过算法完成和/或检查。此外,当然,一旦您有DFA识别语言的交集,您就可以构建一个与该语言匹配的正则表达式。如果你从正则表达式开始,你可以制作DFA。这绝对是可计算的。
编辑:
因此,要构建笛卡尔积分机,需要两个DFA。设M1 =(E,q0,Q1,A1,f1),M2 =(E,q0',Q2,A2,f2)。在两种情况下,E是输入字母,q0是开始状态,Q是所有状态的集合,A是接受状态的集合,f是转换函数。构建M3 ......
如果我没有犯任何错误,L(M3)= L(M1)与L(M2)相交。干净,是吗?
答案 1 :(得分:2)
我创建了一个PHP implementation的Patrick87答案。除了通过笛卡尔积计机实现交叉点之外,我还使用De Morgan实现了一种用于查找DFA交点的替代算法。
Intersection( DFA_1, DFA_2 ) === ! UNION( ! DFA_1, ! DFA_2 )
* ! is defined as negation
这对于DFA非常有效,因为完全定义的DFA(定义了每个可能的转换状态的那些)的否定只是将所有非最终状态添加到最终状态集并从最终状态中移除所有当前最终状态set(非final - > final,final - > non> final)。 DFA联盟可以通过将它们转换为NFA然后创建一个新的起始节点来轻松完成,该节点通过lambda变换连接联合DFA的旧起始节点。
除了解决交叉点问题外,library I created还能够将NFA确定为DFA并将Regex转换为NFA。
编辑:
我创建了一个webapp,允许使用我在这个问题(以及其他人)中学到的东西,对正则表达式语言进行这种转换。