直接把作业帖上来是不是有点不太公道呀。。。

无所谓啦反正各位看着开心就行

KMP算法

对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前缀的最长后缀的长度(也可以理解为那个前缀的结束位置),在匹配中,若$P[i]$与$S[j]$失配,则令$i=N [i-1] +1$ ,否则$i=i+1,j=j+1$

现考虑如何构造$N$ ,设当前以计算出$N[1..i-1]$ ,则令$k=N[i-1]$ ,若 $P[k+1]=P[i]$,则令$N[i]=k+1$ ,否则令$k=N[k]$ 。重复上述过程,直至找到$N[i]$

可证该算法能在$\Theta(|P|) $ 的时间内构造出前缀函数$N$ ,在$\Theta (|S|)$ 的时间内完成匹配,总的时间复杂度为$\Theta(|S|+|P|)$

KMP算法的正确性证明

先证明匹配过程的正确性:

在过程中,若$P[1..q]$ 与$S[s+1...s+q]$ 匹配,而$P[q+1]$与$S[s+q+1]$ 失配,那么由$N$的定义可立即得出$P[1..N[q]]$ 与 $S[s+q-N[q]+1...s+q]$ 匹配,而$S[1...t]$与$S[s+q-t+1...s+q]$ 失配$(N[q]<t<q)$ ,即只需检验$P[N[q]+1]$ 与$S[s+q+1]$ 的匹配情况即可,匹配过程的正确性即可得证。

接下来证明前缀函数$N$计算的正确性:

令$N^*[q]= \{N[q],N^{(2)}[q],…,N^{(t)}[q]\}$ 其中$N^{(t)}[q]=N^{(t-1)}[q],N^{(0)}[q]=N[q]$ ,那么$N^*[q]$ 为以q位置为结束的可以匹配到前缀的后缀的所有长度(即匹配到所有前缀的位置),同时有$N[q]-1\in N^*[q-1]$ ,因此只需从大到小枚举$N^*[q-1]$ 中的元素并通过判断即可得出$N[q]$ 。
KMP算法的时间复杂度证明

在匹配时:$i,j$增长了$|S|$ ,而在$i=N[i-1]+1$ 中,$i$ 至少减少1,即该语句至多执行了$|S|$次,因此时间复杂度为$\Theta(|S|)$。

构造前缀函数$N$ 时: 我们考虑k的变化,我们可以得到,在每次$k=N[k]$ 中,$k$ 至少减少1,又因为$k$随$i$增加了$|P|$次,即该语句至多执行$|P|$ 次,因此时间复杂度为$\Theta(|P|)$ 。

因此总的时间复杂度为$\Theta(|S|+|P|)$ 。
KMP算法的优化

我们希望通过优化,为了减少失配的概率,因此提出如下改进:

在构造$N'$数组时,当$P[k+1]=P[i]$ 时,若$P[i+1]=P[k+2]$ 则$N'[i]=k+1$ 否则$N'[i]=N'[k+1]$ 。
该优化的正确性证明

在匹配时,我们发现,若$P[q+1]$ 与$S[s+q+1]$失配,同时$P[q+1]=P[N^{(t)}[q]+1]$ ,则$P[N^{(t)}[q]+1]$一定与$S[s+q+1]$ 失配,因此若$P[N[q]+1]=P[q+1]$ ,则该比较一定失配,无需考虑。

在该优化中,由该函数的递归求法可得,$N'[q]=max\{N^*[q]且P[q+1]\neq P[N^{(t)}[q]+1]\}$ ,因此$N'[q]$ 依旧能枚举完所有可能匹配的前缀,同时减少失配概率。
该优化对算法空间与时间复杂度的影响

由于该优化只是改变了N数组的构造方法,因此对空间复杂度无影响。

时间复杂度的证明同KMP的证明,可得对最坏情况下的时间复杂度无影响

由于该算法避免了出现$P[N[q]+1]=P[q+1]$的情况,因此对于有较多重复子串的模式串有较好的优化效果(如aaaab,abcabcabcd)

最新文章

  1. 理解 neutron(15):Neutron linux-bridge-agent 创建 linux bridge 的简要过程
  2. 订制DOM选择器
  3. Xamarin的不归路-生成安卓错误
  4. C#开发分享:如何改变系统鼠标样式
  5. 使用php技术实现无刷新的上传文件
  6. ubuntu14.04LTS编译MUDOS v22.2b14
  7. 5分钟破解wpa2密码(转)
  8. meta 标签 关键字 用处
  9. My集合框架第四弹 HashTable(链表解决冲突)
  10. python运维开发之第十天
  11. pagefile.sys怎么删除
  12. RMQPOJ3264
  13. JAVA连接数据库 #03# HikariCP
  14. sqlserver还原数据库失败,sql2008备份集中的数据库备份与现有的xxx数据库不同
  15. Jquery获取选中的文本值
  16. cannot ignore cache if it is not cached [ArcGIS Catalog 10]
  17. ubuntu16.04下安装kdevelop和汉化
  18. Daily Scrum (2015/10/30)
  19. Python黑魔法,一行实现并行化
  20. iOS:友盟SDK第三方登录 分享及友盟统计的使用

热门文章

  1. Java编程思想非主流知识点
  2. 【转】安卓Java的虚拟机区别
  3. thinkPHP 模板中变量的使用
  4. Html在网页、页面中放置Swf、Flash 背景
  5. AIX上面Oracle数据库相关启动
  6. java程序的工作原理
  7. LoadRunner
  8. Spring3.2AOP实现需要添加的三个包
  9. JS可维护性代码
  10. 实现一个类 Vue 的 MVVM 框架