题目链接:https://vjudge.net/contest/220679#problem/B
题目大意:
输入一个T,表示有T组测试数据;
每组测试数据包括一个字符串W,T,T长度大于W小于1000000,w长度小于10000,计算W匹配到T中成功的次数;
需要注意的是:
第一次将匹配成功的位置得到后,若从匹配到的位置开始算起,会超时,实际上没必要,每次模式串匹配成功时,都将个数+1,然后从next数组的下一位继续开始匹配,直至待匹配串结束
代码如下:实际上就是将kmp裸题稍微改一下。
若两个不同的匹配没有交集则j=0,若存在交集则j=next[j]
#include <stdio.h> #include <string.h> int next[10005]; char str1[1000005], str2[10005]; int cnt; //匹配的子串个数 void get_next(int len2)//生成next数组 { int i = 0, j = -1; next[0] = -1; while (i<len2) { if (j == -1 || str2[i] == str2[j]) { i++; j++; next[i] = j; } else j = next[j]; } } void kmp(int len1, int len2)//kmp算法 { int i = 0, j = 0; get_next(len2); while (i<len1) { if (j == -1 || str1[i] == str2[j]) { ++i; ++j; } else j = next[j]; if (j == len2) { cnt++; j = next[j]; //找到一个匹配的串后,模式串的起点从next数组下一个点继续匹配 } } } int main() { int n; int len1, len2; scanf("%d", &n); getchar(); while (n--) { gets_s(str2); gets_s(str1); len1 = strlen(str1); len2 = strlen(str2); cnt = 0; kmp(len1, len2); printf("%d\n", cnt); } return 0; }
2018-04-18