有點腦殼疼,過段時間再回頭看看吧
是因爲樸素匹配算法的時間複雜度過高,爲降低時間複雜度,有了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;
}