您的位置:首页 > 其它

白书上的AC自动机模板

2014-08-04 20:26 204 查看
//trie,感觉就是字典树
struct Trie{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
Trie() {sz = 1;memset(ch[0],0,sizeof(ch[0]));}
int idx(char c) { return c-'a';}
void insert(char *s,int v){
int u=0,n=strlen(s);
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]=v;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
<pre name="code" class="cpp">//获取失配函数
void getFail()
{
queue<int>q;
f[0]=0; //失配函数
for(int c=0;c<sigma_size;c++){
int u=ch[0][c];
if(u){f[u]=0;q.push(u);last[u]=0}  //last数组存的是当前节点前一个单词的末尾节点坐标
}
while(!q.empty()){

int r=q.front();q.pop();
for(int c=0;c<sigma_size;c++){
int u=ch[r][c];
if(!u){ch[r][c]=ch[f[r]][c];continue;} //对所有不存在的边建立状态转移边
q.push(u);
int v=f[r];
while(v && !ch[v][c]) v=f[v];   //直到找到匹配节点或者返回到root点
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]);
j=ch[j][c];     //因为对不存在的点也建立了状态转移边
if(val[j]) print(i,j);
else if(last[j]) print(i,j);
}
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: