您的位置:首页 > 其它

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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: