hdu 1686 Oulipo (KMP)(计算模式串匹配的次数——与已匹配的字串可以有交集)
<题目链接>
题目大意:
输入一个T,表示有T组测试数据;
每组测试数据包括一个字符串W,T,T的长度$\le10^6$,$W$的长度$\le 10^4$,计算W匹配到T中成功的次数;
需要注意的是:
第一次将匹配成功的位置得到后,若从匹配到的位置开始算起,会超时,实际上没必要,每次模式串匹配成功时,都将个数+1,然后从next数组的下一位继续开始匹配,直至待匹配串结束
代码如下:实际上就是将kmp裸题稍微改一下。
若两个不同的匹配没有交集则j=0,若存在交集则j=next[j]
#include <bits/stdc++.h> using namespace std; const int N1 = 1e6+5, N2 = 1e4+5; int nxt[N2]; char str1[N1],str2[N2]; int cnt; //匹配的子串个数 inline void get_nxt(int len2){ int i = 0, j = -1; nxt[0] = -1; while (i<len2){ if (j == -1 || str2[i] == str2[j])nxt[++i]=++j; else j = nxt[j]; } } inline void kmp(int len1, int len2){ int i = 0, j = 0; get_nxt(len2); while (i<len1){ if (j == -1 || str1[i] == str2[j])++i,++j; else j = nxt[j]; if (j == len2)++cnt,j=nxt[j]; //找到一个匹配的串后,模式串的起点从nxt数组下一个点继续匹配 } } int main(){ int n;scanf("%d", &n);getchar(); int len1,len2; while (n--){ gets(str2);gets(str1); len1 = strlen(str1); len2 = strlen(str2); cnt = 0; kmp(len1, len2); printf("%d\n", cnt); } }
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。