【暑假】[实用数据结构]KMP
2016-03-30 17:19
218 查看
KMP算法
KMP算法是字符串匹配算法,可以在O(n)的时间完成,算法包含两部分,分别是:构造适配函数与两串匹配。
失配边的使用大大提高了算法效率,可以理解为已经成功匹配的字符不在重新匹配,因为我们已经知道它是什么,对应到算法中 匹配失败后应该在最大前缀之后继续匹配,因为某后缀已与最大前缀匹配成功而不用重新比较。
以下为代码实现:
有趣的是,在这里发现了作者的一个小错误,如果使字符串成功匹配所有位置且KMP算法可以完成的话,需要加入语句j=0;而在课本中这条语句是没有的。
KMP算法是字符串匹配算法,可以在O(n)的时间完成,算法包含两部分,分别是:构造适配函数与两串匹配。
失配边的使用大大提高了算法效率,可以理解为已经成功匹配的字符不在重新匹配,因为我们已经知道它是什么,对应到算法中 匹配失败后应该在最大前缀之后继续匹配,因为某后缀已与最大前缀匹配成功而不用重新比较。
以下为代码实现:
1 const int maxn = 1000 + 5; 2 3 void getFail(char* P,int* f){ //构造失配边 4 int n=strlen(P); 5 f[0]=f[1]=0; 6 for(int i=0;i<n;i++){ //自己和自己匹配 7 int j=f[i]; 8 while(j && P[i]!=P[j]) j=f[j]; 9 f[i+1]= P[i]==P[j]? j+1 : 0; 10 } 11 } 12 13 //可以如是理解f数组,f[i]表示到i与后缀成功匹配的最大前缀的下一指针 14 //f数组节约了算法时间,对于已知(已比较)的字符不在重新比较 15 16 void KMP(char* T,char* P){ 17 int f[maxn]; 18 int n=strlen(T), m=strlen(P); 19 getFail(P,f); 20 int j=0; 21 for(int i=0;i<n;i++){ 22 while(j && T[i] != P[j]) j=f[j]; //沿失配边走 23 if(T[i]==P[j]) j++; 24 if(j==m) { printf("%d\n",i-m+1); j=0; } //成功匹配P,输出匹配点 25 //将j重调为0代表重新检查,否则P[j]调用出错 26 } 27 }
有趣的是,在这里发现了作者的一个小错误,如果使字符串成功匹配所有位置且KMP算法可以完成的话,需要加入语句j=0;而在课本中这条语句是没有的。
相关文章推荐
- netmap分析(3)-原理分析之数据结构关系
- Java数据结构——双端链表
- 《数据结构》 栈代码操作集合
- 数据结构(java语言描述)串与数组——文件加解密
- 常见的数据结构和算法
- 【数据结构】链表与实现分析
- 数据结构--Dijkstra算法最清楚的讲解
- 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
- Java数据结构——链表-单链表
- 数据结构
- Intellij IDEA快捷键整理
- Java数据结构——解析算术表达式
- 统计文章中单词的字数并按照出现的频率排序(treeSet)
- 数据结构之队列的实现
- 数据结构(五)--最小生成树(普利姆算法、克鲁斯卡尔算法)
- 数据结构(四)--B树、B-树、B+树、B*树
- 数据结构线性表的两种存储形式顺序表和单链表的比较
- 数据结构之栈的实现
- 链表的所有操作(总结)
- 数据结构之双端(通用)链表的实现