模板:

struct Ac_Automation
{
    int ch[MAXNNODE][SIGMA_SIZE];
    int val[MAXNNODE];
    int fail[MAXNNODE],last[MAXNNODE];
    bool symbol[MAXNNODE];
    int sz;
    Ac_Automation() {sz = 1;memset(ch[0],0,sizeof(ch[0]));symbol[0] = false;}
    int idx(char c)
    {
        return c - 'a';
    }

    void insert(char * s)
    {
        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]));
                symbol[sz] = false;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        symbol[u] = true;//最后的叶子节点给与信息v
    }

    //建立字典树

    void get_fail()
    {
        queue<int>q;
        fail[0] = 0;
        for (int c = 0 ; c < SIGMA_SIZE ; c++)
        {
            int u = ch[0][c];
            if (u)
            {
                fail[u] = 0;
                q.push(u);
                last[u] = 0;
            }
        }
        while (!q.empty())
        {
            int r = q.front();q.pop();
            if (symbol[fail[r]]) symbol[r] = true;
            for (int c = 0 ; c < SIGMA_SIZE ; c++)
            {
                int u = ch[r][c];
                if (u == 0)
                {
                    ch[r][c] = ch[fail[r]][c];
                    continue;
                }
                q.push(u);
                int v = fail[r];
                while (v && !ch[v][c]) v = fail[v];
                fail[u] = ch[v][c];
                last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
            }
        }
    }

    void print(int j)
    {
        if (j)
        {
           // printf("%d\n",val[j]);
           // cnt[val[j]]++;
            print(last[j]);
        }
    }

    void Find(char * T)
    {
        int n = strlen(T);
        int j = 0;
        for (int i = 0 ; i < n ; i++)
        {
            int c = idx(T[i]);
           // while(j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);//print是功能函数
        }
    }

    void init()
    {
        sz = 1;
        memset(ch[0],0,sizeof(ch[0]));
        symbol[0] = false;
    }

    Matrix build_mat()
    {
        Matrix ret = Matrix(sz + 1);
        for (int i = 0 ; i < sz ; i++)
            for (int j = 0 ; j < SIGMA_SIZE ; j++)
                if (symbol[i] == false && !symbol[ch[i][j]])
                    ret.mat[i][ch[i][j]]++;
        for (int i = 0 ; i <= sz ; i++)
            ret.mat[i][sz] = 1;
        return ret;
    }
}src;

 

HDU 2222 Keywords Search

找出主串中有多少个模式串出现

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
int ans;
const int MAXNNODE = 500010;
const int SIGMA_SIZE = 26;
struct Ac_Automation
{
    int ch[MAXNNODE][SIGMA_SIZE];
    int val[MAXNNODE];
    int cnt[MAXNNODE];
    int sz;
    Ac_Automation() {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] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        cnt[u]++;
        val[u] = v;//最后的叶子节点给与信息v
    }

    //建立字典树

    int fail[MAXNNODE],last[MAXNNODE];
    int get_fail()
    {
        queue<int>q;
        fail[0] = 0;
        for (int c = 0 ; c < SIGMA_SIZE ; c++)
        {
            int u = ch[0][c];
            if (u)
            {
                fail[u] = 0;
                q.push(u);
                last[u] = 0;
            }
        }
        while (!q.empty())
        {
            int r = q.front();q.pop();
            for (int c = 0 ; c < SIGMA_SIZE ; c++)
            {
                int u = ch[r][c];
                if (u == 0)
                {
                    ch[r][c] = ch[fail[r]][c];
                    continue;
                }
                q.push(u);
                int v = fail[r];
                while (v && !ch[v][c]) v = fail[v];
                fail[u] = ch[v][c];
                last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
            }
        }
    }

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

    void Find(char * T)
    {
        int n = strlen(T);
        int j = 0;
        for (int i = 0 ; i < n ; i++)
        {
            int c = idx(T[i]);
           // while(j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            if (val[j]) print(j);
            else if (last[j]) print(last[j]);//print是功能函数
        }
    }

    void init()
    {
        sz = 1;
        memset(ch[0],0,sizeof(ch[0]));
        memset(cnt,false,sizeof(cnt));
    }
}src;
int N;
char input[60];
char tag[1000005];
int main()
{
    //freopen("sample.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&N);
        gets(input);
        src.init();
        ans = 0;
        for (int i = 0 ; i < N; i++)
        {
            gets(input);
            src.insert(input,i + 1);
        }
        scanf("%s",tag);
        src.get_fail();
        src.Find(tag);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2018-10-26
  • 2021-06-21
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-11-30
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案