根據牛客網左神講的內容改編而成。KMP算法通過最長前後綴實現了加速,可以通過反證法加以證明,有興趣的可以參考算法導論。
判斷pattern在Text的什麼位置出現的
#include<cstdio>
#include<cstring>
int next[100];
int ans=0;
void getNext(char s[], int len){ //此處的next數組存的是i-1前不含本身的最長前後綴長度
next[0] = -1; //人爲規定
next[1] = 0; //人爲規定
int i = 2;
int cn = 0; //跳的位置
while(i < len){
if(s[i-1] == s[cn]){
next[i++]=++cn;
}else if(cn > 0){
cn=next[cn];
}else{
next[i++]=0;
}
}
}
int KMP(char text[], char pattern[]){
int n = strlen(text);
int m = strlen(pattern);
getNext(pattern, m);
int i=0,j=0;
while(i <n && j <m){
if(text[i] == pattern[j]){
i++;
j++;
}else if(next[j] == -1){ //pattern串已經滑到頭了
i++;
}else{
j = next[j]; //繼續滑動至最大前綴
}
}
return j==m?(i-j):-1; // 找到則返回找到的位置,找不到返回-1
}
int main(){
char text[]="habahwriteababacidufd";
char pattern[]="ababac";
int x =KMP(text,pattern);
printf("%d",x);
return 0;
}
統計模式串Pattern在匹配串Text中出現的次數
#include<cstdio>
#include<cstring>
int next[100];
void getNext(char s[], int len){ //此處的next數組存的是i-1前不含本身的最長前後綴長度
next[0] = -1; //人爲規定
next[1] = 0; //人爲規定
int i = 2;
int cn = 0; //跳的位置
while(i < len){
if(s[i-1] == s[cn]){
next[i++]=++cn;
}else if(cn > 0){
cn=next[cn];
}else{
next[i++]=0;
}
}
}
int KMP(char text[], char pattern[]){
int n = strlen(text);
int m = strlen(pattern);
int ans = 0;
getNext(pattern, m);
int i=0,j=0;
while(i <n && j <m){
if(text[i] == pattern[j]){
i++;
j++;
}else if(next[j] == -1){ //pattern串已經滑到頭了
i++;
}else{
j = next[j]; //繼續滑動至最大前綴
}
if(j==m){
j=next[j-1];
ans++;
}
}
return ans;
}
int main(){
char text[]="habahwriteababacidufd";
char pattern[]="aba";
int x =KMP(text,pattern);
printf("%d",x);
return 0;
}