AC自动机

#include <iostream>            //poj 1204 Word Puzzles
using namespace std ;
struct Node
{
Node
*next[26];
Node
*fail;
int des; //标记要查找的单词最后一个字母出现的地方
Node():des(-1),fail(NULL)
{
memset(next,NULL,
sizeof(next));
}
int heigh;
}
*root,*q[100000];
char table[1005][1005],ch[5000]; //table[1005][1005]为单词表,ch[5000]为要查找的单词
int res[1005][3],found[1005]; //res[i]记录要查找的第i个单词的结果
int L,C,W,count,flag,cnt=1;
int head,tail;
void insert(int rank)
{
Node
*p=root;
int index,i;
for(i=0;ch[i];++i)
{
index
=ch[i]-'A';
if(p->next[index]==NULL)
{
p
->next[index]=new Node(); //申请空间
}
p
=p->next[index];
p
->heigh=i+1;
}
p
->des=rank;
}

void build_ac_automation()
{
head
=tail=0;
root
->fail=NULL;
q[head
++]=root;
while(head!=tail)
{
Node
*temp=q[tail++];
Node
*p=NULL;
for(int i=0;i<26;++i)
{
if(temp->next[i]!=NULL)
{
if(temp==root)
temp
->next[i]->fail=root;
else
{
p
=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp
->next[i]->fail=p->next[i];
break;
}
p
=p->fail;
}
if(p==NULL)
temp
->next[i]->fail=root;
}
q[head
++]=temp->next[i];
}
}
}
}

void search(int i,int j,int way)
{
Node
*p=root;
int index;
while(i>=0&&i<L&&j>=0&&j<C)
{
index
=table[i][j]-'A';
while(p->next[index]==NULL&&p!=root)
p
=p->fail;

p
=p->next[index];
p
=(p==NULL)?root:p;
Node
*temp=p;
while(temp!=root&&temp->des!=-1&&!found[temp->des])
{
found[temp
->des]=1;
count
++;
int start_i=i,start_j=j,h=temp->heigh-1;
switch (way)
{
case 1:
start_i
+=h;break;
case 2:
start_i
+=h;start_j-=h;break;
case 3:
start_j
-=h;break;
case 4:
start_i
-=h;start_j-=h;break;
case 5:
start_i
-=h;break;
case 6:
start_i
-=h;start_j+=h;break;
case 7:
start_j
+=h;break;
case 8:
start_i
+=h;start_j+=h;break;
default:
break;
}
res[temp
->des][0]=start_i;
res[temp
->des][1]=start_j;
res[temp
->des][2]=way;
temp
=temp->fail;
}
if(count==W)
{
flag
=1;break; //表示查找完毕
}
switch(way) //1 代表正北,顺时针依次是 东北2,正东3,东南4,正南5,西南6,正西7,西北8。
{
case 1:
i
-=1;break;
case 2:
i
-=1;j+=1;break;
case 3:
j
+=1;break;
case 4:
i
+=1;j+=1;break;
case 5:
i
+=1;break;
case 6:
i
+=1;j-=1;break;
case 7:
j
-=1;break;
case 8:
i
-=1;j-=1;break;
default:break;
}
}
}
int main()
{
root
=new Node(); //对root初始化
scanf("%d%d%d",&L,&C,&W);
for(int i=0;i<L;++i)
{
scanf(
"%s",table[i]);
}
for(int i=0;i<W;++i)
{
scanf(
"%s",ch);
insert(i);
}
build_ac_automation();

//for(int i=0;i<L&&!flag;++i) //tle,因为重复计算了很多次
//{
// for (int j=0;j<C&&!flag;++j)
// {
// for(int k=1;k<=8&&!flag;++k)
// {
// search(i,j,k);
// }
// }
//}


//列举出每一个方向
for(int i=0;i<L&&!flag;++i)
{
search(i,
0,3);
search(i,C
-1,7);
search(i,
0,2);
search(i,C
-1,6);
search(i,
0,4);
search(i,C
-1,8);
}
for(int j=0;j<C&&!flag;++j)
{
search(
0,j,5);
search(L
-1,j,1);
search(L
-1,j,2);
search(
0,j,6);
search(
0,j,4);
search(L
-1,j,8);
}
for(int i=0;i<W;++i)
printf(
"%d %d %c\n",res[i][0],res[i][1],(char)(res[i][2]+64));
return 0 ;
}

//http://www.cppblog.com/mythit/archive/2009/04/21/80633.html

  

posted on 2011-08-22 11:57  sysu_mjc  阅读(163)  评论(0编辑  收藏  举报

导航