KMP算法中关于构造DFA部分的纠结
2015-04-16 15:23
357 查看
在《算法》(Sedgewick)一书中,看到了KMP算法,看了一遍没懂,但觉得挺神奇的,就花费了几个小时深入的理解。
算法的原理其实不难,难的就是那个神奇的DFA数组,我的大部分时间也都是花费在这个数组上面的。
以下从豆瓣读书找来的问题及答案,看着不错,就给抠来了~
出处:http://book.douban.com/subject/19952400/discussion/59623403/
5.3.3.4 构造DFA(p766)
图5.3.8 计算模式ABABAC的重启状态的DFA模拟
没看明白.
以致代码中的:
X = dfa[pat.charAt(j)][X] ;
也不能理解.
答:
dfa[text.charAt(i)][j]是指当文本字符串的字符s[i]与模式字符串的字符p[j]比较后下一次与文本字符串的字符s[i+1]比较的模式字符串的字符位。
当文本字符串的第i位字符与模式字符串的第j位进行匹配时,如果此两位字符匹配,则说明下一步应该为i++ j++之后再比较,也就是说当txt.charAt(i)==pat.charAt(j)时,有dfa[pat.charAt(j)][j]=j+1。
当文本字符串的第i位字符与模式字符串的第j位检测到不匹配时,设txt.charAt(i)==c,c!=pat.charAt(j),但文本字符串的s[i-j...i-1]这部分与模式字符串的p[0...j-1]这部分是匹配的。这时从文本字符串的i-j位置起已不可能出现匹配字符串,现在已不用管s[i-j]字符,现在的问题是依次输入s[i-j+1...i-1]c后会进入什么状态,由于s[i-j...i-1]这部分与模式字符串的p[0...j-1]这部分是匹配的,也就是说现在的问题是依次输入p[1...j-1]c后会进入什么状态。
引入一个状态指示数组X,X[j]是指正确输入p[1...j-1]后进入的状态,输入p[1...j-1]c后进入的状态就是dfa[c][X[j]](在X[j]状态时输入c),即dfa[c][j]=dfa[c][x[j]]。
而计算X[]数组的方法为递推方法:X[j+1]为正确输入p[1...j]后进入的状态,即正确输入p[1...j-1]p[j]后进入的状态,也就是在X[j]状态时输入p[j]时进入的状态,就是dfa[pat.charAt[j]][X[j]],即递推公式为:X[j+1]=dfa[pat.charAt[j]][X[j]],而X[0]手动初始化为0。
由于X[]数组为辅助数据,且为递推的,所以书中仅使用了一个变量X来指示当前的X[j],我觉得理解起来很不方便,所以这里由数组代替。
PS:看着这里,我还是糊里糊涂的,这个X的计算总是理解不了~哎~
算法的原理其实不难,难的就是那个神奇的DFA数组,我的大部分时间也都是花费在这个数组上面的。
以下从豆瓣读书找来的问题及答案,看着不错,就给抠来了~
出处:http://book.douban.com/subject/19952400/discussion/59623403/
问:
5.3.3.4 构造DFA(p766)
图5.3.8 计算模式ABABAC的重启状态的DFA模拟
没看明白.
以致代码中的:
X = dfa[pat.charAt(j)][X] ;
也不能理解.
答:
dfa[text.charAt(i)][j]是指当文本字符串的字符s[i]与模式字符串的字符p[j]比较后下一次与文本字符串的字符s[i+1]比较的模式字符串的字符位。
当文本字符串的第i位字符与模式字符串的第j位进行匹配时,如果此两位字符匹配,则说明下一步应该为i++ j++之后再比较,也就是说当txt.charAt(i)==pat.charAt(j)时,有dfa[pat.charAt(j)][j]=j+1。
当文本字符串的第i位字符与模式字符串的第j位检测到不匹配时,设txt.charAt(i)==c,c!=pat.charAt(j),但文本字符串的s[i-j...i-1]这部分与模式字符串的p[0...j-1]这部分是匹配的。这时从文本字符串的i-j位置起已不可能出现匹配字符串,现在已不用管s[i-j]字符,现在的问题是依次输入s[i-j+1...i-1]c后会进入什么状态,由于s[i-j...i-1]这部分与模式字符串的p[0...j-1]这部分是匹配的,也就是说现在的问题是依次输入p[1...j-1]c后会进入什么状态。
引入一个状态指示数组X,X[j]是指正确输入p[1...j-1]后进入的状态,输入p[1...j-1]c后进入的状态就是dfa[c][X[j]](在X[j]状态时输入c),即dfa[c][j]=dfa[c][x[j]]。
而计算X[]数组的方法为递推方法:X[j+1]为正确输入p[1...j]后进入的状态,即正确输入p[1...j-1]p[j]后进入的状态,也就是在X[j]状态时输入p[j]时进入的状态,就是dfa[pat.charAt[j]][X[j]],即递推公式为:X[j+1]=dfa[pat.charAt[j]][X[j]],而X[0]手动初始化为0。
由于X[]数组为辅助数据,且为递推的,所以书中仅使用了一个变量X来指示当前的X[j],我觉得理解起来很不方便,所以这里由数组代替。
PS:看着这里,我还是糊里糊涂的,这个X的计算总是理解不了~哎~
相关文章推荐
- KMP算法 (c++ 构造完整的DFA)
- 看看你写的类定义是否合理?--关于部分构造的问题
- 关于HTML5语义内容的学习(部分)
- 关于MD5,SALT与SHA1的部分HASH算法解析
- 国务院办公厅关于2011年部分节假日安排的通知
- 五、关于idea使用的部分建议
- ffmpeg中关于ffplay部分的概要分析-2
- 关于桌面进程出现问题的部分解决方案
- 关于“选择特大字体,图库详情中部分信息行间距太大”的问题
- 拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元
- 《编写高质量代码:改善C++程序的150个建议》读书笔记5(关于异常处理的部分)
- 关于C#静态构造方法的几点说明
- 关于Qt中Udp通信过程中的接收数据部分注意
- 正则表达式DFA构造方法
- 关于黑莓恢复中的部分功能分辨
- 关于Core Animation(转载部分内容)
- 纠结了很久的问题,关于sql中单字段重复,取一条全字段的方法。
- 关于从list或者数组中随机抽取部分不重复元素的问题探究
- 关于 java.util.concurrent 您不知道的 5 件事,第 1 部分
- 关于IE浏览器高版本,右侧滚动条会遮盖部分网页内容解决?