浅谈KMP算法
来源:互联网 发布:域名ip地址查询 编辑:程序博客网 时间:2024/06/03 19:24
课上学了KMP算法之后有几个地方很是迷茫,课下就查了点资料,这里做下总结,今后忘了还能回来看一下。
首先,KMP算法的主要目的就是比较两个字符串时避免不必要的回溯。一个字符串可能会出现字符串头部和尾部有重复的现象,KMP算法就是根据这个现象,在比较字串时,不在简单地向后移一位,而是在后移时,跳过首位相同的部分再开始比较。例如:判断 ABCDABD 是否是 ABCDABEABCDABD 的子串,
ABCDABEABCDABD
ABCDABD
判断到第6位时 E 和 D 不同,但它的前两位 AB 和 子串的前两位 AB 相同,所以之后直接移动到
ABCDABEABCDABD
ABCDABD
所以这时子串和 E 比较的位的 C 的下标就等于 D 的前一位 B 的首位重复的位数
这里就需要对子串进行一个预处理,就是算出它的每一位对应的部分匹配值,也就是前后重复的位数,对于 ABCDABD 来说,就是 0000120,先上代码
#include <string>#include <assert.h>int* Next(string P){ int m = P.length(); assert( m > 0 ); //若 m = 0 则退出 int *N = new int[m]; assert( N != NULL ); N[0] = 0; for(int i = 1; i < m; i ++){ int k = N[i - 1]; while(k > 0 && P[i] != P[k]){ k = N[k - 1]; } if(P[i] == P[k]){ N[i] = k + 1; }else{ N[i] = 0; } } return N;}其中 k 表示尾部要进行比较的上一位有几个字符重复,也代表接下来头部要进行比较的位的下标,k - 1 表示比较时头部重复部分最后一个字符的下标,i 表示第 i 个字符
我比较难理解的就主要是
while(k > 0 && P[i] != P[k]){ k = N[k - 1]; }这两行,翻译成中文就是 当一个子串满足去掉一个字符重复 k 个,加上这个字符却不重复 k + 1 个时,对于这个字符来说,它的重复个数等于当前头部重复部分最后一个字符的重复个数,满足条件则继续循环
循环出来后,条件应该为k == 0 || P[i] == P[k],之后的逻辑就简单了,如果前等于后,重复个数就加1,否则为0
KMP算法的代码就是
int KMPStrMartching(string T, string P, int startIndex){ //判断P是否为T的子串,是的话返回开始的下标 int *N = Next(P); int lastIndex = T.length() - P.length(); if((lastIndex - startIndex) < 0) return (-1); int i = 0, j = 0; for(i = startIndex; i < T.length(); i ++){ while(P[j] != T[i] && j > 0) j = N[j - 1]; if(P[j] == T[i]) j ++; if(j == P.length()){ delete N; N = NULL; return (i - j + 1); } } delete N; N = NULL; return (-1);}
阅读全文
0 0
- kmp算法浅谈
- 浅谈KMP算法
- 浅谈KMP算法
- 浅谈kmp算法
- 浅谈KMP算法
- 浅谈扩展KMP算法
- 浅谈KMP算法
- 浅谈KMP算法的延伸
- 浅谈KMP算法及实现
- 浅谈字符串匹配的KMP算法
- 浅谈字符串匹配算法—BF算法及KMP算法
- 浅谈字符串匹配算法—BF算法及KMP算法
- 浅谈KMP
- 浅谈Manacher算法与扩展KMP之间的联系
- BZOJ 3670 浅谈KMP算法的拓展应用
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- 欢迎使用CSDN-markdown编辑器
- Machine Learning学习之岭回归
- path类,流和文件流
- Map集合
- [Oracle 11g r2(11.2.0.4.0)]案例分析7-丢失本地心跳导致的集群重新配置
- 浅谈KMP算法
- C++风格_类
- 洛谷P2661 信息传递 (NOIp2015)
- kubernetes Pod 调度到指定的 Node
- 批量doc转docx的两种方法--Office Migration Planning Manager使用、插件使用
- Kotlin类和对象(二)——属性和字段
- 正则表达式(记忆口诀)
- Android 源码在线查看地址
- Android7.0的相机调用和适配适配