KMP(SOJ3596)
2014-03-21 21:16
113 查看
(2012-07-15 19:28:27)
SOJ3596: http://cstest.scu.edu.cn/soj/problem.action?id=3596
这道题采用的算法是DP+KMP,也是我做KMP的题中最具挑战性的一道。
首先利用KMP算法将所有的word在text中的所有位置(包括起点和终点)存到一个struct数组中。
至于DP,设xiaoye[i]表示以text[i]为结尾的结果,则求xiaoye[i]即是对所有的满足:j<i,xiaoye[j]>0,并且从字符text[j+1]到字符text[i]是某一个word条件的xiaoye[j]作xiaoye[i]=xiaoye[i]+xiaoye[j]的处理。但是直接按照这个思路处理会超时,倒过来进行就会大大提高效率。
这需要对struct数组进行预处理,也就是下面的cmp函数。
代码:
SOJ3596: http://cstest.scu.edu.cn/soj/problem.action?id=3596
这道题采用的算法是DP+KMP,也是我做KMP的题中最具挑战性的一道。
首先利用KMP算法将所有的word在text中的所有位置(包括起点和终点)存到一个struct数组中。
至于DP,设xiaoye[i]表示以text[i]为结尾的结果,则求xiaoye[i]即是对所有的满足:j<i,xiaoye[j]>0,并且从字符text[j+1]到字符text[i]是某一个word条件的xiaoye[j]作xiaoye[i]=xiaoye[i]+xiaoye[j]的处理。但是直接按照这个思路处理会超时,倒过来进行就会大大提高效率。
这需要对struct数组进行预处理,也就是下面的cmp函数。
代码:
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int next[1005]; char text[1000005]; int sum; struct node { char pattern[1005]; }word[1005]; struct Node { int a; int b; }position[1000005]; void get_next(char *pattern) { int j=0; int k=-1; next[0]=-1; while(pattern[j]) { if(k==-1 || pattern[j]==pattern[k]) { ++j; ++k; if(pattern[j]!=pattern[k]) next[j]=k; else next[j]=next[k]; } else k=next[k]; } } void KMP(char *pattern) { int i=0; int j=0; int result=0; int lP=strlen(pattern); while(text[i]) { if(text[i]==pattern[j]) { i++; j++; } else if(next[j]==-1) { j=0; i++; } else j=next[j]; if(j==lP-1) { position[sum].a=i-lP+1; position[sum++].b=i-1; j=next[j];//这里的next[j]即是next['0']的值,显然只能>=0. } } } int cmp(Node x,Node y) { return x.a<y.a || (x.a==y.a && x.b<y.b); } int xiaoye[1000005]; int main() { int test; int n; int i; scanf("%d",&test); while(test--) { sum=0; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s",word[i].pattern); strcat(word[i].pattern,"0"); } scanf("%s",text); for(i=0;i<n;i++) { get_next(word[i].pattern); KMP(word[i].pattern); } int lT=strlen(text); memset(xiaoye,0,sizeof(xiaoye)); sort(position,position+sum,cmp); for(i=0;i<sum;i++) { if(position[i].a==0) xiaoye[position[i].b]++; else { xiaoye[position[i].b]=(xiaoye[position[i].b]+xiaoye[position[i].a-1])%835672545; } } printf("%d\n",xiaoye[lT-1]); } return 0; }
相关文章推荐
- KMP学习之路【KMP】
- POJ 1961 Period——kmp求最小循环节
- 【KMP】【模板】
- HDU 1711 Number Sequence (KMP模板)
- Power Strings(POJ2406)(KMP)
- [扩展kmp] hdu6153 A Secret
- 【KMP】POJ-3461 Oulipo
- FZU 2275 Game(KMP)
- KMP
- [SDUT](3311)数据结构实验之串三:KMP应用 ---KMP(串)
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法
- HDOJ3336 KMP简单应用+模板程序
- poj 1961 KMP运用之循环节的问题
- HDU 3613 Best Reward manacher || kmp || extkmp
- POJ 1961 Period (KMP)
- Codeforces #269 (Div. 2)D. MUH and Cube Walls(KMP)
- hdu3374最小表示法+KMP
- HDU 1711 Number Sequence——kmp
- HDU 2203 KMP
- hdu 6068--Classic Quotation(kmp+DP)