KMP算法及其应用
来源:互联网 发布:软件测试英文自我介绍 编辑:程序博客网 时间:2024/05/18 01:33
前言
今天学习了一个新算法:KMP算法 其实很久以前学过早忘了
KMP算法是用于处理字串问题的算法。
参考Matrix67的博客:KMP算法详解|Matrix67
KMP算法的原理
假设有字符串A和B,要求判断B是否是A的字串
其实就是对于每个i,求最大的j,使得
能匹配j指针就往后跳一个
否则就需要往回退
如下图:
我们希望往回退得越少越好,
通过上图可以发现,其实最佳方案就是 最长相同前后缀
对字符串B的每个前缀字串,找一个最长的长度l,使得长度为l的前后缀相同
这个可以预处理出来,第i个前缀的长度l记为next[i]
那么每次不匹配就往回退next[j]即可
只要出现j==m的情况就说明B是A的字串
代码如下:
for (int i=1,j=0;i<=n;i++){ while (j>0&&B[j+1]!=A[i]) j=nxt[j]; if (B[j+1]==A[i]) j++; if (j==m){ //do something…… }}
下面来说预处理的事。
怎样得到next[]?假设已经得到next[1~i-1],现在求next[i]
设next[i-1]为j,如果B[j+1]==B[i],那么next[i]=next[i-1]+1
否则需要缩小j的范围。
有读者可能会发现,寻找next[i]的过程其实就是将B[1~i-1]与B[]匹配的过程
所以回退next[j]即可
代码如下:
nxt[1]=0;for (int i=2,j=0;i<=n;i++){ while (j>0&&B[j+1]!=B[i]) j=nxt[j]; if (B[j+1]==B[i]) j++; nxt[i]=j;}
接下来证明复杂度。
通过上面的代码可以发现,j指针最多向后跳n次
而j在任何时候都是大于0的,所以回退也是O(n)级别的
所以KMP算法的复杂度是O(n)
KMP算法的应用
通过next[]数组,可以得到一个字符串的最小周期以及最小循环节
最小周期为n-next[n],如果周期能整除n,最小循环节就是周期
否则是n
阅读全文
2 0
- KMP算法及其应用
- KMP算法及其扩展应用
- kmp总结及其应用
- kmp算法的思想及其简单应用(java版)
- Java数据结构-串及其应用-KMP模式匹配算法
- KMP及其改进算法
- KMP算法及其优化
- kmp算法及其拓展
- KMP算法及其实现
- KMP及其改进算法
- KMP算法及其优化
- KMP算法及其优化算法
- kmp算法及其c++实现
- kmp算法的应用
- KMP算法应用
- 经典算法之KMP算法及其优化
- 递归算法及其应用
- A*算法及其应用
- 海外 | 潜伏!一个叫Fruitfly 的macOS和OS X后门竟然潜伏了5年之久
- #java 读取windows AD域sid乱码问题
- AndroidStudio中遇到的情况
- “ windows套接字初始化失败”解决方法
- 大话设计模式笔记(二)——商品促销 策略模式
- KMP算法及其应用
- 观察者模式
- poj1279Art Gallery
- 编译的classpath 未加入v4和v7库
- 移除数组中的重复元素
- 数据库导出数据到文本文件的两种方式
- CloudStack管理员文档
- golang协程 通道channel阻塞
- MyEclipse/Eclipse快捷键