AC自动机模板

AC自动机,继承自Trie

用于多个模式串的匹配


struct ACauto :public Trie
{
  int cnt;
  int last[maxn];
  int nex[maxn];

  ACauto()
  {
    cnt=0;
    sz=1;
    val[0]=0;
    memset(ch[0],0,sizeof ch[0]);
  }
  void clear()
  {
    cnt=0;
    Trie::clear();
  }

  void calc(int j)
  {
    if (j!=0)
    {
      cnt++;
      calc(last[j]);
    }
  }

  void get_fail()
  {
    int f=0,r=-1;
    nex[0]=0;
    for (int c=0;c<maxsize;c++)
    {
      int u=ch[0][c];
      if (u!=0)
      {
        nex[u]=0;
        q[++r]=u;
        last[u]=0;
      }
    }

    while (f<=r)
    {
      int x=q[f++];
      for (int c=0;c<maxsize;c++)
      {
        int u=ch[x][c];
        if (u==0) continue;
        q[++r]=u;
        int v=nex[x];
        while (v>0 && ch[v][c]==0) v=nex[v];
        nex[u]=ch[v][c];
        last[u]=val[nex[u]]>0?nex[u]:last[nex[u]];
      }
    }
  }

  void find(const char *T)
  {
    for (int i=0,j=0;T[i]!='\0';i++)
    {
      int c=idx(T[i]);
      while (j>0 && ch[j][c]==0) j=nex[j];
      j=ch[j][c];
      if (val[j]!=0)
        calc(j);
      else if (last[j]!=0)
        calc(last[j]);
    }
  }
};


——————————————我是分割线—————————————————

update@2014_11_14

去掉了失配函数,将所有转移一视同仁,方便了在AC自动机上进行DP

struct ACauto :public Trie
{
  int cnt;
  int last[maxn];
  int nex[maxn];

  ACauto()
  {
    cnt=0;
    sz=1;
    val[0]=0;
    memset(ch[0],0,sizeof ch[0]);
  }
  void clear()
  {
    cnt=0;
    Trie::clear();
  }

  void calc(int j)
  {
    if (j!=0)
    {
      cnt++;
      calc(last[j]);
    }
  }

  void get_fail()
  {
    int f=0,r=-1;
    nex[0]=0;
    for (int c=0;c<maxsize;c++)
    {
      int u=ch[0][c];
      if (u!=0)
      {
        nex[u]=0;
        q[++r]=u;
        last[u]=0;
      }
    }

    while (f<=r)
    {
      int x=q[f++];
      for (int c=0;c<maxsize;c++)
      {
        int u=ch[x][c];
        if (u==0)
        {
          ch[x][c]=ch[nex[x]][c];
          continue;
        }
        q[++r]=u;
        int v=nex[x];
        nex[u]=ch[v][c];
        last[u]=val[nex[u]]>0?nex[u]:last[nex[u]];
      }
    }
  }

  void find(const char *T)
  {
    get_fail();
    for (int i=0,j=0;T[i]!='\0';i++)
    {
      int c=idx(T[i]);
      j=ch[j][c];
      if (val[j]!=0)
        calc(j);
      else if (last[j]!=0)
        calc(last[j]);
    }
  }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值