解决问题:用于求解一个串是否在另一个串中出现以及出现了多少次?
时间复杂度:O(n+m) 空间复杂度:O(m)
算法:
1、next[ ]数组的求解
2、根据next[ ]数组进行匹配
KMP算法next[ ]数组求解:
1、next[ ]数组保存部分匹配值,用于字符串分析,不用于kmp算法的求解
void Pre_kmp(char x[],int m,int next[]){///原始next数组:部分匹配值
int j=next[0]=0;
for(int i=1;i<m;++i)
{
while(0!=j && x[i]!=x[j])
j = next[j-1];
if (x[i]==x[j])
j++;
next[i] = j;
}
}
2、next[ ]数组一般求解方法
void Pre_kmp(char x[],int m,int next[]){
int j=next[0]=-1;
int i=0;
while(i<m){
if(-1!=j&&x[i]!=x[j]) j=next[j];
next[++i]=next[++j];
}
}
3、针对aaaaaaaaaaaaaab这样的模板串进行优化的next[ ]数组方法
void Pre_kmp(char x[],int m,int next[]){///优化后
int j=next[0]=-1;
int i=0;
while(i<m){
while(j!=-1&&x[i]!=x[j]) j=next[j];
if(x[++i]==x[++j]) next[i]=next[j];///优化处理
else next[i]=j;
}
}
KMP算法标准模板:
#include <iostream>
#define MAXN 10010
using namespace std;
void Pre_kmp(char x[],int m,int kmpNext[]){
int i,j;
j=kmpNext[0]=-1;
i=0;
while(i<m){
while(-1!=j&&x[i]!=x[j]) j=kmpNext[j];
if(x[++i]==x[++j]) kmpNext[i]=kmpNext[j];
else kmpNext[i]=j;
}
}
int next[MAXN];
int KMP_Count(char x[],int m,char y[],int n){
//x是模式串,y是主串
int ans=0;
Pre_kmp(x,m,next);///预处理得到模式串x的next数组
int i,j;
i=j=0;
while(i<n){
while(j!=-1 && y[i]!=x[j]) j=next[j];///j==-1表示第一个字符x[0]与y[i]不匹配
i++;j++;
if(j>=m){
ans++;
j=next[j];
}
}
return ans;
}