用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - c++代码库

AC自动机

2016-10-28 作者: 云代码会员举报

[c++]代码库

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

using namespace std;

const int maxn = 1e6 + 5;

struct Node
{
    int cnt;
    Node *fail;
    Node *child[26];
    Node()
    {
        cnt = 0;
        fail = NULL;
        for(int i = 0;i < 26;i++)
            child[i] = NULL;
    }
};

char s[maxn];
Node *root;

void makeTrie(char *kw)
{
    Node *p = root;
    for(int i = 0;kw[i] != '\0';i++)
    {
        int ix = kw[i] - 'a';
        if(p->child[ix] == NULL)
            p->child[ix] = new Node();
        p = p->child[ix];
    }
    p->cnt++;
}

void makefail()
{
    queue<Node *> q;
    q.push(root);
    while(!q.empty())
    {
        Node *p = q.front();
        q.pop();
        for(int i = 0;i < 26;i++)
        {
            Node *f = p->fail;
            if(p->child[i])
            {
                //找p->child[i] 的失配指针
                while(f)
                {
                    if(f->child[i])
                    {
                        p->child[i]->fail = f->child[i];
                        break;
                    }
                    else
                        f = f->fail;
                }
                if(f == NULL)
                    p->child[i]->fail = root;
                //
                q.push(p->child[i]);
            }
        }
    }
}

int acauto()
{
    int ans = 0;
    Node *p = root;
    for(int i = 0;s[i] != '\0';i++)
    {
        int ix = s[i] - 'a';
        //开始匹配当前字符
        while(p)
        {
            if(p->child[ix])
            {
                p = p->child[ix];
                break;
            }
            else
                p = p->fail;
        }
        //如果没有匹配的
        if(p == NULL)
        {
            p = root;
            continue;
        }
        //成功匹配一个字符
        Node *t = p;
        while(t != root)
        {
            if(t->cnt)
            {
                ans += t->cnt;
                t->cnt = 0;
            }
            t = t->fail;
        }
    }
    return ans;
}
void _free(Node *p)
{
    for(int i = 0;i < 26;i++)
        if(p->child[i])
            _free(p->child[i]);
    free(p);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int N;
        scanf("%d",&N);
        root = new Node();
        for(int i = 0;i < N;i++)
        {
            char keyword[55];
            scanf("%s",keyword);
            makeTrie(keyword);
        }
        makefail();
        scanf("%s",s);
        printf("%d\n",acauto());
        _free(root);
    }
    return 0;
}

[源代码打包下载]




网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...