KMP算法用于解决字符串匹配问题,它能够在O(n+m)的时间内完成文本串与模式串的匹配。C与C++中也有提供字符串匹配函数,比如C中的strstr(),C++中string类下的find()函数,但是对于大数据效果都没有KMP好。KMP算法主要是计算失配指针next[],然后顺着失配边走,直到可以匹配为止。
计算失配指针next[];
void GetNext(){
int m = strlen(t); //字符串t为模式串
int k = 0;
next[0] = next[1] = 0;
for (int i = 1; i<m; i++){
k = next[i];
while (k && t[i] != t[k]) k = next[k];
if (t[i] == t[k]) next[i+1] = k + 1;
else next[i+1] = 0;
}
}
完成字符串匹配;
void KMP(){
int n = strlen(s); //字符串s为文本串
int m = strlen(t);
GetNext();
int k = 0;
for (int i=0; i<n; i++){
while (k && s[i] != t[k]) k = next[k];
if (s[i] == t[k]) k++;
if (k == m){} //找到了一个匹配
}
}
KMP模板题 poj3461
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<stack>
#define ll long long
#define MAX 1000010
#define INF INT_MAX
#define eps 1e-8
using namespace std;
char s[MAX],t[MAX];
int next[MAX];
void GetNext(){
int m = strlen(t);
int k = 0;
next[0] = next[1] = 0;
for (int i = 1; i<m; i++){
k = next[i];
while (k && t[i] != t[k]) k = next[k];
if (t[i] == t[k]) next[i+1] = k + 1;
else next[i+1] = 0;
}
}
int KMP(){
int cnt = 0;
int n = strlen(s);
int m = strlen(t);
GetNext();
int k = 0;
for (int i=0; i<n; i++){
while (k && s[i] != t[k]) k = next[k];
if (s[i] == t[k]) k++;
if (k == m) cnt++;
}
return cnt;
}
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%s%s",t,s);
printf("%d\n",KMP());
}
return 0;
}
KMP算法的应用—求前缀字符串的最短循环节,有的前缀可能没有循环节,当 next[i] && i % (i-next[i]) == 0,最短循环节为i / (i-next[i]);
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<string>
#include<set>
#include<stack>
#define ll long long
#define MAX 1000010
#define INF INT_MAX
#define eps 1e-8
using namespace std;
int next[MAX];
char t[MAX];
void GetNext(){
int m = strlen(t);
int k = 0;
next[0] = next[1] = 0;
for (int i = 1; i<m; i++){
k = next[i];
while (k && t[i] != t[k]) k = next[k];
if (t[i] == t[k]) next[i+1] = k + 1;
else next[i+1] = 0;
}
}
int main(){
int n,cas = 0;
while (scanf("%d",&n) && n > 0){
cas++;
scanf("%s",t);
GetNext();
printf("Test case #%d\n",cas);
for (int i=2; i<=n; i++){
if (next[i] && i % (i-next[i]) == 0){
printf("%d %d\n",i, i / (i - next[i]));
}
}
printf("\n");
}
return 0;
}