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;
    }
    


  • 相关阅读:
    Java 工程名上有个红色叹号
    TestNG 入门教程
    字典序问题
    统计数字问题
    sniffer 简介
    【转】IE浏览器快捷键大全
    批处理 延时不完全总结【转】
    批处理(Batch)---批处理脚本。
    windows系统命令行
    计算机网络
  • 原文地址:https://www.cnblogs.com/riskyer/p/3243998.html
Copyright © 2011-2022 走看看