您的位置:首页 > 其它

POJ 3461 KMP 模板题 字串出现次数

2017-10-07 00:00 120 查看

参考博客

从头到尾彻底理解KMP

http://blog.csdn.net/v_july_v/article/details/7041827

http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html

http://www.cnblogs.com/destinydesigner/archive/2009/10/17/1585063.html

http://blog.csdn.net/hackbuteer1/article/details/7319115

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define LL long long
int const MAX = 1e6 + 1;
int const INF = 1 << 30;
double const EPS = 0.00000001;
using namespace std;

int fail[10010], n;
char text[1000010], pat[10010];

void get_fail(char p[], int f[]){
int j = 0, k = -1, tlen = strlen(p);
f[0] = -1;
while (j < tlen){
if (k == -1 || p[j] == p[k]){//匹配成功时
j++;
k++;
f[j] = k;
} else {
k = f[k];
}
}
}

// 优化后的fail数组
void get_failval(char p[], int f[]){
int j = 0, k = -1, tlen = strlen(p);
f[0] = -1;
while (j < tlen){
if (k == -1 || p[j] == p[k]){//匹配成功时
j++;
k++;
if (p[j] == p[k]){
f[j] = f[k];
} else {
f[j] = k;
}
f[j] = k;
} else {
k = f[k];
}
}
}
// 返回t中字串p出现的次数,字串可重叠
int kmp(char t[], char p[]){
int ans = 0;
get_failval(p, fail);
//i 指向当前读入的字符处,j指向当前准备匹配的字符处
int i = 0, j = 0;
int tlen = strlen(t), plen = strlen(p);
while (i < tlen){
if (j == -1 || t[i] == p[j]){
i++, j++;
} else {
j = fail[j];
}
if (j == plen){
ans++;
j = fail[j];
}
}
return ans;
}
int main(){
scanf("%d", &n);
while (n--){
scanf("%s %s", pat, text);;
printf("%d\n", kmp(text, pat));
}
// int tlen = strlen(text);
// get_fail(text, fail);
// for (int i = 0; i < tlen; i++)
//     printf("%2c ", text[i]);
// printf("\n");
// for (int i = 0; i < tlen; i++)
//     printf("%2d ", fail[i]);
return 0;
}


next数组的另一种求法

#include <cstdio>
#include <iostream>
#include <cstring>

const int maxn = 1000010;

char T[maxn], W[10010];
int next[10010];//记录模式串的next指针

// void get_next(int len){//获得模式串的next指针
//     next[0] = -1;
//     int i = 0, j = -1;
//     while (i < len){
//         if (j == -1 || W[i] == W[j])
//             next[++i] = ++j;
//         else
//             j = next[j];
//     }
// }
void get_next(int len){//获得模式串的next指针
next[0] = -1;
int i = 0, j = -1;
while (i < len){
if (j == -1 || W[i] == W[j]){
// next[++i] = ++j;
i++;
j++;
if (W[i] != W[j]){
next[i] = j;
} else {
next[i] = next[j];
}
} else
j = next[j];
}
}
7fe0

int KMP(){
int len1 = strlen(T), len2 = strlen(W);
get_next(len2);
int i = 0, j = 0;
int ans = 0;
while (i < len1){
if (j == -1 || T[i] == W[j])
i++, j++;
else
j = next[j];
if (j == len2)
ans++, j = next[j];
}
return ans;
}

int main(){
int n;
scanf("%d", &n);
while (n--){
scanf("%s", W);
scanf("%s", T);
int ans = KMP();
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  KMP ACM 模板