您的位置:首页 > 编程语言

AC自动机代码

2014-07-22 22:16 369 查看
HDU 2222 http://acm.hdu.edu.cn/showproblem.php?pid=2222

#include <stdio.h>
#include <string.h>

//memset会消耗内存
//不要每次初始化都memset所有数组 - -!

#define MAXN 500010
#define MAXS 1000010
#define ROOT 1

char str[MAXS];
int node_num;

int ch[MAXN][26],fail[MAXN],cnt[MAXN],que[MAXN];

void init()
{
node_num = 2;
memset(ch[ROOT],0,sizeof(int)*26);
}

void insert_node(char *str)
{
char *ptr = str;
int p=ROOT;
while(*ptr)
{
int idx=(*ptr)-'a';
if(ch[p][idx]==0)
{
ch[p][idx] = node_num++;
memset(ch[node_num-1],0,sizeof(int)*26);
fail[node_num-1]=cnt[node_num-1]=0;
}
p = ch[p][idx];
ptr++;
}
cnt[p]++;
}

void build_fail()
{
int head,tail;
head=0;
tail=1;
que[0]=ROOT;
fail[ROOT] = 0;
while(head<tail)
{
int p = que[head++];
int q;
for(int i=0;i<26;i++)
{
if(ch[p][i])
{
q = fail[p];
que[tail++] = ch[p][i];
while(q!=0&&ch[q][i]==0)
{
q = fail[q];
}
fail[ch[p][i]] = q==0?ROOT:ch[q][i];
}
}
}
}

int ac_match(char *str)
{
char *ptr = str;
int p = ROOT;
int num = 0;
while(*ptr)
{
int idx = (*ptr)-'a';
while(p!=0&&ch[p][idx]==0)//match the char
{
p = fail[p];
}
p = p==0?ROOT:ch[p][idx];
int tmp = p;
while(tmp!=ROOT)//find the suffix word
{
num += cnt[tmp];
cnt[tmp] = 0;
tmp = fail[tmp];
}
ptr++;
}
return num;
}

int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
while(n--)
{
scanf("%s",str);
insert_node(str);
}
build_fail();
scanf("%s",str);
//dfs(ROOT);
printf("%d\n",ac_match(str));
}
return 0;
}


HDU 2896 http://acm.hdu.edu.cn/showproblem.php?pid=2896

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int MAXN = 505*200;
const int CS = 128;
const int MAXS = 10010;

int ch[MAXN][CS],fail[MAXN],info[MAXN];
int que[MAXN];
int pool,rt;
char str[MAXS];

int alloc_node();

int cmp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;
}

void init()
{
pool = 1;
rt = alloc_node();
}

int alloc_node()
{
memset(ch[pool],0,sizeof(int)*CS);
fail[pool] = info[pool] = 0;
return pool++;
}

void insert_node(char *str,int no)
{
char *ptr = str;
int p = rt;
while(*ptr)
{
int idx = *ptr;
if(ch[p][idx]==0)
{
ch[p][idx] = alloc_node();
}
p = ch[p][idx];
ptr++;
}
info[p] = no;
}

void build_fail()
{
int head,tail;
head = 0;
tail = 1;
que[head] = rt;
fail[rt] = 0;
while(head<tail)
{
int p = que[head++];
int q;
for(int i=0;i<CS;i++)
{
if(ch[p][i])
{
q = fail[p];
while(q!=0&&ch[q][i]==0)
{
q = fail[q];
}
fail[ch[p][i]] = q==0?rt:ch[q][i];
que[tail++] = ch[p][i];
}
}
}
}

int ac_match(char *str,int result[])
{
int num = 0;
char *ptr = str;
int p = rt;
while(*ptr)
{
int idx = *ptr;
while(p!=0&&ch[p][idx]==0)
{
p = fail[p];
}
p = p==0?rt:ch[p][idx];
int q = p;
while(q!=rt)
{
if(info[q])
{
result[num++] = info[q];
}
q = fail[q];
}
ptr++;
}
return num;
}

//debug
void dfs(int p)
{
printf("[%d][%d]\n",p,fail[p]);
for(int i=0;i<CS;i++)
{
if(ch[p][i])
{
dfs(ch[p][i]);
}
}
}

int main()
{
int n,m,num,tot;
while(scanf("%d%*c",&n)!=EOF)
{
init();
tot = 0;
for(int i=0;i<n;i++)
{
gets(str);
insert_node(str,i+1);
}
build_fail();
scanf("%d%*c",&m);
for(int i=0;i<m;i++)
{
gets(str);
//dfs(rt);
num = ac_match(str,que);
qsort(que,num,sizeof(int),cmp);
if(num)
{
printf("web %d:",i+1);
for(int j=0;j<num;j++)
{
printf(" %d",que[j]);
}
printf("\n");
tot++;
}
}
printf("total: %d\n",tot);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: