zoukankan      html  css  js  c++  java
  • HDU 2222 Keywords Search(AC自动机)题解

    题意:给出模式串,问你主串出现了几种模式串。

    思1路:ac自动机模板题。参考q学姐:av6295004

    ac自动机的基本原理就是在trie上建Fail值,这样我每次失配就去找当前的最长后缀去匹配,一直到完全失配为止,这样我就找遍了所有的模式串。

    代码:

    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 5e5 + 10;
    const int maxM = 1e6 + 10;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e4 + 7;
    struct Aho{
        struct state{
            int next[26];
            int fail, cnt;
        }node[maxn];
        int size;
        queue<int> q;
    
        void init(){
            for(int i = 0; i < maxn; i++){
                memset(node[i].next, 0, sizeof(node[i].next));
                node[i].fail = node[i].cnt = 0;
            }
            size =  1;
            while(!q.empty()) q.pop();
        }
    
        void insert(char *s){
            int len = strlen(s);
            int now = 0;
            for(int i = 0; i < len; i++){
                char c = s[i];
                if(node[now].next[c - 'a'] == 0)
                    node[now].next[c - 'a'] = size++;
                now = node[now].next[c - 'a'];
            }
            node[now].cnt++;
        }
    
        void build(){
            node[0].fail = -1;
            q.push(0);
    
            while(!q.empty()){
                int u = q.front();
                q.pop();
                for(int i = 0; i < 26; i++){
                    if(node[u].next[i]){
                        if(u == 0) node[node[u].next[i]].fail = 0;
                        else{
                            int v = node[u].fail;
                            while(v != -1){
                                if(node[v].next[i]){
                                    node[node[u].next[i]].fail = node[v].next[i];
                                    break;
                                }
                                v = node[v].fail;
                            }
                            if(v == -1) node[node[u].next[i]].fail = 0;
                        }
                        q.push(node[u].next[i]);
                    }
                }
            }
        }
    
        int get(int u){ //匹配规则
            int ret = 0;
            while(u){
                ret += node[u].cnt;
                node[u].cnt = 0;
                u = node[u].fail;
            }
            return ret;
        }
    
        int match(char *s){
            int ret = 0, now = 0;
            int len = strlen(s);
            for(int i = 0; i < len; i++){
                char c = s[i];
                if(node[now].next[c - 'a'])
                    now = node[now].next[c - 'a'];
                else{
                    int p = node[now].fail;
                    while(p != -1 && node[p].next[c - 'a'] == 0){
                        p = node[p].fail;
                    }
                    if(p == -1) now = 0;
                    else now = node[p].next[c - 'a'];
                }
                if(node[now].cnt){
                    ret += get(now);
                }
            }
            return ret;
        }
    }ac;
    
    char s[maxM];
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            int n;
            scanf("%d", &n);
            ac.init();
            for(int i = 0; i < n; i++){
                scanf("%s", s);
                ac.insert(s);
            }
            scanf("%s", s);
            ac.build();
            printf("%d
    ", ac.match(s));
        }
        return 0;
    }
  • 相关阅读:
    TCP Socket 粘包
    Toast连续弹出的问题
    SDK Build Tools revision (19.0.3) is too low for project Minimum required is 19.1.0
    数据结构精要------直接选择和堆排序算法
    hdoj 2199 Can you solve this equation? 【二分枚举】
    云端数据遭觊觎 安全问题不容忽视
    leetcode || 58、Length of Last Word
    【安全加密技术】非对称加密
    无处不在的微创新——验证码的故事
    IDLE经常使用快捷键汇总
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11174904.html
Copyright © 2011-2022 走看看