KMP算法学习笔记
来源:互联网 发布:java runnable 编辑:程序博客网 时间:2024/05/17 21:41
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。(百度的嘻嘻)
KMP难在对于next数组的构建与理解
next[i]的定义是 到 i 处已找到的最长相同前后缀的长度
next的作用是当字符串s1和字符串s2匹配到s1[i]和s2[j]时, 若s1[i]和s2[j]不相等,就不必再把j重新从0开始找,而是跳到和当前指针j有相同前缀的地方。
s1[i]和s2[j]不相等,但之前有一部分是相同的
举个例子:比如说 ababc 和 ababd, 比较到c和d时发生了冲突,但这时发现d的前面有一个ab, c的前面也有一个ab,这时候我们只要跳到前一个ab处就可以继续比较
ababc 和 ababd 中的 c和a了, 省了不少时间
首先我们要理解一波前缀和后缀, 前缀和后缀指的是一个集合
例如 ababa
其前缀为{a,ab,aba,abab}(不包括最后一个)
后缀为{a,ba,aba,baba}(不包括第一个)
可以很清楚的看到,最长前后缀就是 aba, 长度为3
我个人理解的next[i]是跳到与i的后缀 有最长的相同前缀的地方
贴一份next数组构建的代码, 也就是s2的自我匹配
for(i = 1; i < bn; i++){while(j && s2[j]!=s2[i]) j = next[j-1];//指针跳到j-1的最长前缀处//s2[j]!=s2[i],但是既然j>0,说明从s2[0]到s2[j-1]==s2[i-j]到s2[i-1],这时跳到新的j,新的s[j-1]也会等于原来的s[j]if(s2[j]==s2[i]){next[i] = ++j;//next[i] = 当前指针(因为字符串是从0开始的,而指针到j最长前缀为j-1)+1, 同时 j往下移一个指针} }然后贴出完整代码:#include <cstdio>#include <cstring>using namespace std;int next[1001];char s1[1000001], s2[1001];//next[i]指 到 i 处的最长前后缀 int main(){ int i, j = 0, an, bn; scanf("%s%s", s1, s2); an = strlen(s1); bn = strlen(s2); for(i = 1; i < bn; i++){ while(j && s2[j]!=s2[i]) j = next[j-1];//指针跳到j-1的最长前缀处 //s2[j]!=s2[i],但是既然j>0,说明从s2[1]到s2[j-1]==s2[某个位置开始]到s2[i-1],这时跳到新的j,新的s[j-1]也会等于原来的s[j] if(s2[j]==s2[i]){ next[i] = ++j;//next[i] = 当前指针(因为字符串是从0开始的,而指针到j最长前缀为j-1)+1, 同时 j往下移一个指针 } } j = 0; for(i = 0; i < an; i++){ while(j && s1[i] != s2[j]){ j = next[j-1];//如果目前的s1[i]和s2[j]不相等就一直跳到最长前缀处, 直到相等就接着查找 } if(s1[i] == s2[j]) j++;//相等的话就移动s2[]的指针 if(j == bn){ printf("%d\n", i-j+2);//在第几个字母找到的 j = next[j-1];//跳到上一个位置的next处,这样可以下次直接比较s1[i]和s2[j] } } for(i = 0; i < bn; i++) printf("%d ", next[i]); return 0;}可以去B站搜索KMP算法,印度小哥讲的超级详细链接:https://www.bilibili.com/video/av3246487/?from=search&seid=17380554719454557667
阅读全文
1 1
- KMP算法学习笔记
- 学习笔记-KMP算法
- KMP算法 学习笔记
- Kmp算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- 学习笔记-KMP算法
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法学习笔记
- KMP算法:学习笔记
- KMP匹配算法学习笔记
- KMP算法学习笔记(一)
- |算法讨论|KMP 学习笔记
- 排序——快速排序
- 10个值得收藏的实用HTML5代码片段分享
- Cassandra集群名称问题
- ORB特征点检测与匹配
- C#获取相对路径的八种方法
- KMP算法学习笔记
- PAT甲级真题及训练集(1)--1046. Shortest Distance (20)
- python 报错'gbk' codec can't encode character '\ue5d1' in position 0:
- cocos2d-x中实现对话框
- 最长公共子串
- 归并排序
- Android Studio Can't use Subversion command line client:svn
- 【jzoj3221】【HNOI2013】【游走】【高斯消元】【期望】
- 记录Android studio使用所遇到的坑