#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 10010;
int next[MAXN];
//getNext求解长度为len的字符串s的next数组
void getNext(char s[], int len){
int j = -1;
next[0] = -1; //初始化j = next[0] = -1
for(int i = 1; i < len; i++){ //求解next[1] ~ next[len -1]
while(j != -1 && s[i] != s[j + 1]){
j = next[j]; //反复令j = next[j]
} //直到j回退到-1,或是s[i] == s[j + 1]
if(s[i] == s[j + 1]){ //如果s[i] == s[j + 1]
j++; //则next[i] = j + 1,先令j指向这个位置
}
next[i] = j; //令next[i] = j
}
}
//优化后的next数组,getNextval求解长度为len的字符串s的nextval数组
void getNextval(char s[], int len){
int j = -1;
next[0] = -1; //初始化j = nextval[0] = -1
for(int i = 1; i < len; i++){ //求解nextval[1] ~ nextval[len -1]
while(j != -1 && s[i] != s[j + 1]){
j = nextval[j]; //反复令j = nextval[j]
} //直到j回退到-1,或是s[i] == s[j + 1]
if(s[i] == s[j + 1]){ //如果s[i] == s[j + 1]
j++; //令j指向原next[i]的位置
}
//与getNext函数相比只有下面不同
if(j == -1 || s[i + 1] != s[j + 1]){ //j == -1不需要回退
nextval[i] = j; //getNext函数中只有这句
} else {
nextval[i] = nextval[j];
}
}
}
//KMP算法,判断pattern是否是text的子串
bool KMP(char text[], char pattern[]){
int n = strlen(text), m = strlen(pattern); //字符串长度
getNext(pattern, m); //计算pattern的next数组
int j = -1; //初始化j为-1,表示当前还没有任意一位被匹配
for(int i = 0; i < n; i++){ //试图匹配text[i]
while(j != -1 && text[i] != pattern[j + 1]){
j = next[j]; //不断回退,直到j回到-1或text[i]==pattern[j+1]
}
if(text[i] == pattern[j + 1]){
j++; //text[i]与patten[j+1]匹配成功,令j加1
}
if(j == m - 1){ //patten完全匹配,说明pattern是text的子串
return true;
}
}
return false; //执行完text还没匹配成功,说明pattern不是text的子串
}
//KMP算法,统计pattern在text中出现的次数
int KMP_(char text[], char pattern[]){
int n = strlen(text), m = strlen(pattern); //字符串长度
getNext(pattern, m); //计算pattern的next数组
int ans = 0, j = -1; //ans表示成功匹配次数,并初始化j为-1
for(int i = 0; i < n; i++){ //试图匹配text[i]
while(j != -1 && text[i] != pattern[j + 1]){
j = next[j]; //不断回退,直到j回到-1或text[i]==pattern[j+1]
}
if(text[i] == pattern[j + 1]){
j++; //text[i]与pattern[j+1]匹配成功,令j加1
}
if(j == m - 1){ //pattern完全匹配,说明pattern是text的子串
ans++; //成功匹配次数加1
j = next[j]; //让j回退到next[j]继续匹配
}
}
return ans; //返回成功匹配次数
}
int main(){
char text[MAXN], pattern[MAXN];
scanf("%s%s", text, pattern);
printf("%d\n", KMP(text, pattern));
printf("%d\n", KMP_(text, pattern));
return 0;
}
11-03
3万+
06-03
1012