kmp算法是借助于next数组记录匹配过的信息,从而避免了重复回溯的过程,时间复杂度为O(n+m),空间复杂度为O(m),消耗了一个next数组的长度。代码如下:
#include <iostream>
#include <string>
using namespace std;
void getNext( string &p , int *next ){
int len = p.size();
int i = 0 , j = -1;
next[i] = -1;
while( i < len ){
if( j == -1 || p[i] == p[j] ){
i++;
j++;
if ( i < len ){
if( p[i] != p[j] ){
next[i] = j;
}else{
next[i] = next[j];
//如果字符串 str 第 k 个字符与模式串 p 的第 i 个字符不等,
//则 str 的第 k 个字符肯定与模式串的第 j 个字符不同(因为p[i] == p[j])
}
}
}else{
j = next[j];
}
}
}
int kmp( string &str , string &p ){
int *next = new int[ p.size() ];
getNext( p , next );
int len1 = str.size();
int len2 = p.size();
int i = 0 , j = 0;
while( i < len1 && j < len2 ){
if( j == -1 || str[i] == p[j] ){
i++;
j++;
}else{
j = next[j];
}
}
if( j < len2 ){
return -1;
}else{
return i-len2;
}
}
int main(){
string str;
string p;
cin >> str >> p;
int k = kmp( str , p );
if( k == -1 ){
cout << p << " not match " << str << endl;
}else{
cout << p << " match " << str << " at " << k << endl;
}
}