KMP算法实现
KMP算法主要是用来解决在一个字符串中是否包含另一个字符串的问题,即在字符串str1中是否包含有str2,如果包含,返回str2在str1中的起始位置,如果不包含,返回-1。KMP算法主要通过一个next数组实现匹配加速,next数组记录下str2中对应每一个字符相应的最长前缀和最长后缀相匹配的长度,每次失配后不再从头开始匹配,而是通过next数组跳至str2中相应位置继续往下匹配,实现加速。
时间复杂度分析:假设str1长度为n,str2长度为m,则求解str2的next数组的时间复杂度为O(m),得到next数组后匹配的过程时间复杂度为O(n)。总的时间复杂度为O(m)+O(n),考虑到现实中n往往大于m,即时间复杂度为O(n)。KMP算法是一个非常高效的算法。实现如下:
1 vector<int> getNextArray(string &str2) 2 { 3 vector<int> next(str2.size(), -1); 4 if(str2.size()<=1)return next; 5 next[1]=0; 6 if(str2.size()==2)return next; 7 int i=2, pre=0; 8 while(i<str2.size()) 9 { 10 if(str2[i]==str2[pre]){ 11 next[i]=pre+1; 12 pre=next[i]; 13 ++i; 14 }else if(pre>0){ 15 pre=next[pre]; 16 }else{ 17 next[i++]=0; 18 } 19 } 20 return next; 21 } 22 int KMP(string &str1, string &str2) 23 { 24 if(str1.size()==0 || str2.size()==0 || str2.size()>str1.size())return -1; 25 vector<int> next=getNextArray(str2); 26 int i=0, j=0; 27 while(i<str1.size()) 28 { 29 if(str1[i]==str2[j]){ 30 ++i; 31 ++j; 32 }else if(j>0){ 33 j=next[j]; 34 }else{ 35 ++i; 36 } 37 if(j==str2.size())return i-j; 38 } 39 return -1; 40 }