题目来源:HDU 2896 病毒侵袭
题意:求文本串中有多少个模式串 并且输出下标
思路:直接ac自动机 然后数组记录在输出
我日写了半天结果函数没调用 找了半天错误 你要长记性啊 这种错误犯了好几次了啊 笨蛋
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 10010;
char a[maxn];
bool vis[maxn];
int ans, m;
const int maxnode = 500*210;
const int size = 128;
int ch[maxnode][size];
int val[maxnode];
int f[maxnode];
int sz;
bool id[maxn];
void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void insert(char *s, int v)
{
int u = 0, n = strlen(s);
for(int i = 0; i < n; i++)
{
int c = 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;
f[0] = 0;
for(int c = 0; c < size; c++)
{
int u = ch[0][c];
if(u)
{
f[u] = 0;
q.push(u);
}
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = 0; c < size; c++)
{
int u = ch[r][c];
if(!u)
{
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
f[u] = ch[f[r]][c];
}
}
}
void find(char *s, int num)
{
memset(id, 0, sizeof(id));
int n = strlen(s);
int j = 0;
int flag = 0;
for(int i = 0; i < n; i++)
{
j = ch[j][s[i]];
int temp = j;
while(temp)
{
if(val[temp] > 0)
{
id[val[temp]] = true;
flag = 1;
}
temp = f[temp];
}
}
if(!flag)
return;
ans++;
printf("web %d:", num);
for(int i = 1; i <= m; i++)
if(id[i])
printf(" %d", i);
puts("");
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
m = n;
init();
for(int i = 1; i <= n; i++)
{
char s[555];
scanf("%s", s);
insert(s, i);
}
getFail();
ans = 0;
int t;
scanf("%d", &t);
for(int i = 1; i <= t; i++)
{
scanf("%s", a);
find(a, i);
}
printf("total: %d\n", ans);
}
return 0;
}