ZOJ 3228 Searching the String
2016-05-19 21:23
429 查看
给定一个模式串和n个目标串和对应的权值,当为0时求目标串在模式串里的出现次数(可重叠),当为1是可重叠。主要还是利用fail指针进行判断,当可重叠时直接累加end数组就可,不可重叠时需记录当前串的长度l和之前匹配到的最大下标p,如果l+p<=当前下标i的话即可加上end数组。代码如下
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int INF=1e9; const int MOD=20090717; struct Tree { int next[600010][26],deep[600010],fail[600010]; int L,root; int newnode() { for(int i=0;i<26;i++) { next[L][i]=-1; } L++; return L-1; } void init() { L=0; root=newnode(); deep[root]=0; } int insert(char *s) { int len=strlen(s); int p=root; for(int i=0;i<len;i++) { int id=s[i]-'a'; if(next[p][id]==-1) { next[p][id]=newnode(); deep[next[p][id]]=deep[p]+1; } p=next[p][id]; } return p; } void build() { queue<int>q; int p=root; fail[root]=root; for(int i=0;i<26;i++) { // printf("%d %d %d\n",i,p,next[p][i]); if(next[p][i]==-1) { next[p][i]=root; } else { fail[next[p][i]]=root; q.push(next[p][i]); } } while(!q.empty()) { p=q.front(); q.pop(); for(int i=0;i<26;i++) { if(next[p][i]==-1) { next[p][i]=next[fail[p]][i]; } else { fail[next[p][i]]=next[fail[p]][i]; q.push(next[p][i]); } } } } int cnt[2][600010]; int last[600010]; void query(char *s) { int len=strlen(s); int p=root,ans=0; memset(cnt,0,sizeof(cnt)); memset(last,-1,sizeof(last)); for(int i=0;i<len;i++) { int id=s[i]-'a'; p=next[p][id]; int temp=p; while(temp!=root) { cnt[0][temp]++; if(i-last[temp]>=deep[temp]) { cnt[1][temp]++; last[temp]=i; } temp=fail[temp]; } } } /* void debug() { for(int i = 0;i < L;i++) { printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]); for(int j = 0;j < 26;j++) printf("%2d",next[i][j]); printf("]\n"); } }*/ }; Tree ac; char str[100010]; char s[10]; int typ[100010],pos[100010]; int main() { int cas=1; int n; while(~scanf("%s",str)) { ac.init(); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d %s",&typ[i],s); pos[i]=ac.insert(s); } ac.build(); ac.query(str); printf("Case %d\n",cas++); for(int i=0;i<n;i++) { printf("%d\n",ac.cnt[typ[i]][pos[i]]); } printf("\n"); } }
相关文章推荐
- Linux日常维护命令
- 记mysql 之 delete where 一张很大(20G)的表
- Nginx配置
- C语言按要求打印数组
- ViewPager + Fragment 获取Tag
- java基础学习总结——面向对象
- hdu2767&&hdu3836 Proving Equivalences(Tarjan+缩点)
- 基于注解的组件扫描
- Linux下安装VMware Tools 的方法
- 登录超时跳转页面失败和ajax传递到后台数据乱码
- Codeforces Round #353 (Div. 2)E
- SSM小技巧(一)、Controller中互相调用session中存储的内容
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title
- JavaScript中typeof()函数的定义和用处 getAttribute 4000 () 获取title