【暑假】[实用数据结构]KMP
2015-08-10 20:20
417 查看
KMP算法
KMP算法是字符串匹配算法,可以在O(n)的时间完成,算法包含两部分,分别是:构造适配函数与两串匹配。
失配边的使用大大提高了算法效率,可以理解为已经成功匹配的字符不在重新匹配,因为我们已经知道它是什么,对应到算法中 匹配失败后应该在最大前缀之后继续匹配,因为某后缀已与最大前缀匹配成功而不用重新比较。
以下为代码实现:
有趣的是,在这里发现了作者的一个小错误,如果使字符串成功匹配所有位置且KMP算法可以完成的话,需要加入语句j=0;而在课本中这条语句是没有的。
KMP算法是字符串匹配算法,可以在O(n)的时间完成,算法包含两部分,分别是:构造适配函数与两串匹配。
失配边的使用大大提高了算法效率,可以理解为已经成功匹配的字符不在重新匹配,因为我们已经知道它是什么,对应到算法中 匹配失败后应该在最大前缀之后继续匹配,因为某后缀已与最大前缀匹配成功而不用重新比较。
以下为代码实现:
const int maxn = 1000 + 5; void getFail(char* P,int* f){ //构造失配边 int n=strlen(P); f[0]=f[1]=0; for(int i=0;i<n;i++){ //自己和自己匹配 int j=f[i]; while(j && P[i]!=P[j]) j=f[j]; f[i+1]= P[i]==P[j]? j+1 : 0; } } //可以如是理解f数组,f[i]表示到i与后缀成功匹配的最大前缀的下一指针 //f数组节约了算法时间,对于已知(已比较)的字符不在重新比较 void KMP(char* T,char* P){ int f[maxn]; int n=strlen(T), m=strlen(P); getFail(P,f); int j=0; for(int i=0;i<n;i++){ while(j && T[i] != P[j]) j=f[j]; //沿失配边走 if(T[i]==P[j]) j++; if(j==m) { printf("%d\n",i-m+1); j=0; } //成功匹配P,输出匹配点 //将j重调为0代表重新检查,否则P[j]调用出错 } }
有趣的是,在这里发现了作者的一个小错误,如果使字符串成功匹配所有位置且KMP算法可以完成的话,需要加入语句j=0;而在课本中这条语句是没有的。
相关文章推荐
- nginx高级数据结构源码分析(一)-----双向链表
- 数据结构(15)静态链表
- 数据结构(14)单链表
- 数据结构(13)线性表
- 【暑假】[实用数据结构]前缀树 Trie
- 可视化的数据结构和算法
- MySQL索引背后的数据结构及算法原理
- 数据结构(12)哈希表
- 数据结构(11)无向图相关算法基础
- 数据结构(9)平衡查找树之B树
- 数据结构(8)平衡查找树之红黑树
- 数据结构(7)平衡查找树之2-3树
- 数据结构(6)二叉树
- 数据结构(5)优先级队列与堆排序
- B-tree B+tree 数据结构解析
- 数据结构(4)快速排序
- C源码@数据结构与算法->基数排序
- 数据结构(3)合并排序
- 数据结构(2)基本排序算法
- 程序员必须知道的10个算法和数据结构有哪些?