您的位置:首页 > 其它

【hdu2896】【AC自动机】病毒侵袭

2013-03-21 16:15 197 查看
同样是一道很裸的AC自动机,统计哪些特征码出现在网站的源码上,匹配成功时不要将val赋值为0,因为后面还有文本串要匹配,另外要注意编号需要从小到大输出。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100000 + 10;
const int maxm = 500 + 10;
const int maxlen = 10000 + 10;
const int child_num = 128;
int n,m,tot = 0,sz = 1;
char temp[maxlen],exp[maxlen];
class ACAutumaton
{
private:
int chd[maxn][child_num];
int fail[maxn],val[maxn];
int ans[maxm];
int Q[maxn];
int ID[128];
int cnt;
public:
void Reset()
{
memset(ans,0,sizeof(ans));
cnt = 0;
}
void Insert(char *a,int key)
{
int p = 0;
for(; *a ;a++)
{
int c = *a;
if(!chd[p][c])
{
memset(chd[sz],0,sizeof(chd[sz]));
val[sz] = 0;
chd[p][c] = sz++;
}
p = chd[p][c];
}
val[p] = key;
}
void Construct()
{
int *s = Q,*e = Q;
for(int i = 0;i < child_num;i++)
{
if(chd[0][i])
{
fail[ chd[0][i] ] = 0;
*e++ = chd[0][i];
}
}
while(s != e)
{
int u = *s++;
for(int i = 0;i < child_num;i++)
{
int &v = chd[u][i];
if(v)
{
*e++ = v;
fail[v] = chd[ fail[u] ][i];
}
else v = chd[ fail[u] ][i];
}
}
}
void work(char *T)
{
int n = strlen(T);
int x = 0;
for(int i = 0;i < n;i++)
{
x = chd[x][(int)T[i]];
int tmp = x;
while(tmp && val[tmp] != 0)
{
ans[cnt++] = val[tmp];
tmp = fail[tmp];
}
}
}
void print(int step)
{
if(cnt)
{
sort(ans,ans + cnt);
tot++;
printf("web %d: ",step);
for(int i = 0;i < cnt - 1;i++)
{
printf("%d ",ans[i]);
}
printf("%d\n",ans[cnt-1]);
}
}
}AC;

void init()
{
freopen("hdu2896.in","r",stdin);
freopen("hdu2896.out","w",stdout);
}

void readdata()
{
AC.Reset();
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%s",temp);
AC.Insert(temp,i);
}
AC.Construct();
}

void solve()
{
scanf("%d",&m);
for(int i = 1;i <= m;i++)
{
AC.Reset();
scanf("%s",exp);
AC.work(exp);
AC.print(i);
}
printf("total: %d\n",tot);
}

int main()
{
init();
readdata();
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: