kmp算法
来源:互联网 发布:内涵段子网站源码 编辑:程序博客网 时间:2024/05/19 04:01
这篇文章的确写得不错:http://blog.csdn.net/v_JULY_v/article/details/6111565
这篇更是不错:http://blog.csdn.net/v_JULY_v/article/details/6545192
这次学习kmp算法还是太匆忙,严蔚敏的书上讲得和算法导论有些不同,应该要研究下
这道题目:http://hzzy-010.blog.163.com/blog/static/796923812009914365725/应该也要看看
严蔚敏书上讲得更清晰明了,有时间要研究
下面是我自己的一些想法
上图证明了:
a0a1...ak-1ak=aj-kaj-k+1...aj-1aj
则对于pattern的前j+1序列字符,则有如下可能
⑴ pattern[k+1]==pattern[j+1] 此时overlay(j+1)=k+1=overlay(j)+1
⑵ pattern[k+1]≠pattern[j+1] 此时只能在pattern前k+1个子符组所的子串中找到相应的overlay函数,h=overlay(k),如果此时pattern[h+1]==pattern[j+1],则overlay(j+1)=h+1否则重复(2)过程.
上图是kmp大体的思想。。。。当然这是草图,具体思想,还得看程序:
kmp最难理解的就是next数组的含义,一旦理解之后,算法就理解了
对于模式
0 1 2 3 4 5
a b a a b c
next[5]的含义指,以下标4为结尾的后缀子串与 以下标next[5]-1为结尾的前缀是相同的。
next[5] = 2
以下标4结尾的后缀ab 和以下标2-1结尾的前缀ab是相同的
#include <string>#include <iostream>#include <vector>using namespace std;int kmp(const string &t,const string &p){//首先要对模式p预处理vector<int> next(p.size());next[0] = -1;for (int i=1;i<p.size();++i)//求next[i]{int pre = next[i-1];//先求出段[0,i-1]前缀和后缀最大的相同,即[0,k] = [i-1-k,i-1],使得k最大;while (pre >=0 && p[pre+1]!=p[i]){pre = next[pre];}if(p[pre+1]==p[i])next[i] = pre +1;elsenext[i] = -1;}//查找int tbeg=0,pbeg = 0;while (tbeg<t.size() && pbeg<p.size()){if(t[tbeg]!=p[pbeg]){if(pbeg==0)++tbeg;else{pbeg = next[pbeg -1] +1;//next[i]表示的是在模式串中相同的最大的前缀的结束的下标;因为此时t[tbeg]!=p[pbeg]} //先找出j = next[pbeg-1],使得[0,j] = [pbeg -1-j,pbeg-1];所以[0,j]不需在比较,要比较} //j+1else{++tbeg;++pbeg;}}if(pbeg ==p.size())return tbeg - p.size();return -1;}int main(){string source = "annbcdanacadsannannabnna";string pattern = "anna";cout<<kmp(source,pattern)<<endl;return 0;}
更为简洁效率更高的KMP
void getNext(char *p,vector<int> & next){ int len = strlen(p) - 1; int j = 0; int k = -1; next[0] = -1; while (j < len) { if (k == -1 ||p[j] == p[k]) { ++k; ++j; next[j] = k ; } else k = next[k]; }}int KMP(char *src , char *p) { int pLen = strlen(p); int sLen = strlen(src); vector<int> next(pLen,0); getNext(p,next); int i = 0; int j = 0; while (i < sLen ) { if (j == -1 || src[i] == p[j]) { ++i; ++j; } else j = next[j]; if (j == pLen) return i - j; } return -1;}int main(){cout<< KMP("acabaabaabcacaabc","abaabc");return 0;}
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- KMP算法
- kmp算法
- kmp算法
- KMP算法
- KMP算法
- C++ primer读书笔记之iterater
- 从C到C++——结构体(struct)的涅槃
- linux,windows共享文件夹互访
- js弹出子窗口提交表单后刷新父窗口showModealDialog
- FPGA verilog 实现的1602 时钟计数器
- kmp算法
- shortestPath
- 程序员杂谈
- HttpClient 多线程处理
- SpringMVC入门之普通配置篇
- POJ-1552
- 数据结构-----哈夫曼树的构造以及遍历
- C++面试宝典2011版
- 忙忙忙