题意:计算每种模式串出现的次数
错误:竟然是多组数据。。。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxnode=1001*50+5;
const int sigma_size=26;
int f[maxnode];
int last[maxnode];
int idx(char a){
if(a<='Z'&&a>='A')
return a-'A';
else
return -1;
}
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
int cnt[1001];
void init()
{
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
memset(f,0,sizeof(f));
memset(last,0,sizeof(last));
sz=1;
memset(cnt,0,sizeof(cnt));
}
void insert(char *s,int v)
{
int n=strlen(s);
int u=0;
for(int i=0;i<n;++i)
{
int c=idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
void getFail()
{
queue<int> q;
for(int i=0;i<sigma_size;++i)
{
if(!ch[0][i])continue;
f[ch[0][i]]=0;
last[ch[0][i]]=0;
q.push(ch[0][i]);
}
while(!q.empty())
{
int r=q.front();
q.pop();
for(int c=0;c<sigma_size;++c)
{
int u=ch[r][c];
if(!u)continue;
q.push(u);
int v=f[r];
while(v&&!ch[v][c])v=f[v];
f[u]=ch[v][c];
last[u]= val[f[u]] ? f[u]:last[f[u]];
}
}
}
void find(char* T)
{
int n=strlen(T);
int j=0;
for(int i=0;i<n;++i)
{
int c=idx(T[i]);
if(c==-1){j=0;continue;}
while(j&&!ch[j][c])j=f[j];
j=ch[j][c];
if(val[j])print(j);
else if(last[j])print(last[j]);
}
}
void print(int j)
{
if(j)
{
cnt[val[j]]++;
print(last[j]);
}
}
};
Trie tr;
char s[1001][55];
char tex[2000005];
int main()
{
//freopen("data.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{tr.init();
for(int i=0;i<n;++i)
{
scanf("%s",s[i]);
tr.insert(s[i],i+1);
}
tr.getFail();
scanf("%s",tex);
tr.find(tex);
for(int i=1;i<=n;++i)
{
if(tr.cnt[i])
{
printf("%s: %d\n",s[i-1],tr.cnt[i]);
}
}
}
return 0;
}