有点脑壳疼,过段时间再回头看看吧
是因为朴素匹配算法的时间复杂度过高,为降低时间复杂度,有了KMP算法
KMP算法只需str1遍历一遍即可,重点在于next数组的这个思想。
本文使用c++实现。数据结构书上是用c实现的,next从1开始,而c++中是从0开始,故将next[0]设为取不到的值-1,起始 j 的值改为0;
#include <iostream>
using namespace std;
void kmpherlper(string str,vector<int>& next){
next[0]=-1;
int i=1,j=0;
//i遍历主串
//j表示从第j-next[j]个字符到第j-1个字符与主串从0到next[j]-1是相等的,相等的字符个数是next[j]
//也就是next[j]表示第j个字符前(不包括str[j])有next[j]个重复字符
//例:str=" a b c a b x"
//next[j]:-1 0 0 0 1 2
while(i<str.size()-1){
if(j==-1 || str[i]==str[j])
next[++i]=++j;
else
j=next[j];
}
}
int KMP(string str1,string str2){
vector<int> next(str2.size());
kmpherlper(str2,next);
for(int i=0;i<next.size();i++)
cout<<next[i]<<endl;
int i=0,j=0;
while(i<str1.size() && j<str2.size()){
cout<<"i:"<<i<<':'<<str1[i]<<endl;
cout<<"j:"<<j<<':'<<str2[j]<<endl;
if(j==-1 || str1[i]==str2[j]){
if(j==str2.size()-1) return i;
j++;
i++;
}
else
j=next[j];
}
return 0;
}
int main() {
string str2;
str2="abcabx";
string str1="abcabcabxabcabxa";
int res=KMP(str1,str2);
cout<<res<<endl;
}