zoukankan      html  css  js  c++  java
  • HDU 3065 病毒侵袭持续中

    询问每个模式串在文本传中出现的次数。

    文本串中出现的字符不一定都是大写字母,只需要在匹配的时候,对文本串进行特殊处理,将连续的大写字母段当成合法的一个文本串即可。

    然后……就是简单的统计了。





    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    using namespace std;
    int n, cnt[1010];
    char s[1010][55], t[2000010], a[2000010];
    
    struct AC_Automata {
        #define N 60003
        #define M 26
        int ch[N][M], f[N], val[N], last[N], sz;
    
        void clear() { 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;
            for (int i=0; s[i]; 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];
            }
            val[u] = v;
        }
        void build() {
            queue<int> q;
            f[0] = 0;
            for (int c=0; c<M; c++) {
                int u = ch[0][c];
                if (u) { f[u] = last[u] = 0; q.push(u); }
            }
            while (!q.empty()) {
                int r = q.front(); q.pop();
                for (int c=0; c<M; c++) {
                    int u = ch[r][c];
                    if (!u) { ch[r][c] = ch[f[r]][c]; continue; }
                    q.push(u);
                    f[u] = ch[f[r]][c];
                    last[u] = val[f[u]] ? f[u] : last[f[u]];
                }
            }
        }
        void find(char s[]) {
            int j = 0;
            for (int i=0; s[i]; i++) {
                int c = idx(s[i]);
                j = ch[j][c];
                if (val[j]) print(j);
                else if (last[j]) print(last[j]);
            }
        }
        void print(int j) {
            if (j) {
                cnt[val[j]]++;
                print(last[j]);
            }
        }
    } ac;
    
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        while (scanf(" %d", &n) == 1) {
            ac.clear();
            memset(cnt, 0, sizeof(cnt));
    
            getchar();
            for (int i=1; i<=n; i++) {
                gets(s[i]); ac.insert(s[i], i);
            }
            ac.build();
    
            gets(t);
            int j = 0;
            bool flag = false;
            for (int i=0; t[i]; i++) {
                if (t[i] <= 'Z' && t[i] >= 'A') { flag = true; a[j++] = t[i]; }
                else if (flag) {
                    a[j] = 0; j = 0;
                    flag = false;
                    ac.find(a);
                }
            }
            if (flag) {
                a[j] = 0; j = 0;
                flag = false; ac.find(a);
            }
    
            for (int i=1; i<=n; i++)
                if (cnt[i]) printf("%s: %d
    ", s[i], cnt[i]);
        }
        return 0;
    }
    


  • 相关阅读:
    LeetCode之“数学”:Rectangle Area
    HTML5 简介、HTML5 浏览器支持
    Android EditText获取焦点和失去焦点监听事件
    HTML 速查列表
    HTML URL
    HTML 字符实体
    HTML 脚本
    HTML 颜色值
    HTML 颜色名
    HTML 颜色
  • 原文地址:https://www.cnblogs.com/riskyer/p/3243998.html
Copyright © 2011-2022 走看看