原创文章,转贴请贴出处
偶尔来点纯理论问题。这是一道高级算法作业题,L是正则语言,语言B是L中所有字符串对半开的前一半,证明B也是正则的。
目的明确,构造B的一台NFA,非确定型有限状态机。
要用到“平行NFA”的概念。比如举例另外一个问题:如何判断一个字符串既是正则语言A又是正则语言B?可以构造这样一台NFA,状态集合为Qa*Qb(Qa与Qb为A与B的状态集)。接受集合为Fa*Fb,这样机器的一部分(状态元组的前半部分)匹配语言A,另一部分(元组的后半部分)匹配语言B。
回到我们的主题。假设L的对应DFA为D=(Q,[sum],[delta],q0,F)。构造语言B(L中所有字符串对半开的前一半)的NFA,思路是首先非确定性的猜测输入x在D中运行后到达的状态q(很有可能不是结束状态,因为输入x只是L中某个字符串的一半)。知道q后,构造子NFA:Dq,使用“平行NFA”,状态集为Q*Q,起始状态时(q0,q),接受状态为{q}*F。这个Dq作用是平行的判断x是不是语言A的一半(状态元组的前一半,从q0到q),并且非确定性的判断、猜测x在语言A中对应字符串的后半部分(状态元组的前一半,从q到F)。而且由于x与他的“后半部分”长度相同,从起始状态到接受状态所需的步数是相同的。
上图是为B构造的NFA。为D(L的DFA)中所有的状态qi构造子状态机Dqi。
Dq=(Q*Q,[sum],[delta]’,(q0,q),{q}*F)
其中,Q是D的状态集,[sum]是D的字符集,q0为D 的起始状态,F为D的接受状态,[delta]为D的转移函数。
转移函数[delta]’( (q1,q2),a)) = { ( [delta](q1,a),[delta](q2,b) ) |all b in [sum] }
(对于状态的第一部分,按照原来的状态集进行转移,识别输入x。对于状态的第二部分,非确定性的从q2转移,猜测x的“后半部分”)
参考文献:http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1046126973