POJ 3461 KMP 模板题 字串出现次数
2017-10-07 00:00
120 查看
参考博客
从头到尾彻底理解KMP
http://blog.csdn.net/v_july_v/article/details/7041827http://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; }
相关文章推荐
- POJ 3461 Oulipo【KMP】【模板题】(找出第一个字符串在第二个字符串中出现次数)
- POJ 3461 Oulipo(KMP 模板 一个串在另一个串出现的次数(可重叠|不可))
- POJ 3461 Oulipo(KMP统计子串出现次数)
- POJ 3461 Oulipo(KMP统计子串出现次数)
- poj 3461 Oulipo(kmp统计子串出现次数)
- POJ 3461 Oulipo(KMP:统计一个串出现的次数)
- POJ 3461 Oulipo【KMP,子串出现次数,可重叠】
- POJ 3461 Oulipo (KMP字符串匹配·统计p在s中出现次数)
- [KMP求模式在主串出现次数]POJ 3461 Oulipo
- POJ 3461 Oulipo (KMP,求模版串在文本串中可覆盖出现的次数,constructive)
- [POJ 3461] Oulipo & KMP模板
- POJ 3461 Oulipo (求模式串在文本串中出现的次数)
- poj-3461-kmp模板题。。。
- poj 3461 (模式串T在主串S中出现的次数)
- POJ 3461 Oulipo(模式串在主串中出现的次数)
- POJ 3461 Oulipo (kmp模板)
- POJ - 3461 Oulipo(KMP模板题)
- KMP模板 POJ 3461 KMP模板讲解
- poj 3461 Oulipo (KMP 模板题)
- (串的模式匹配4.6.2)POJ 3461 Oulipo(KMP算法的应用——求一个单词在一行文本中的出现次数)