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


  • 相关阅读:
    668. Kth Smallest Number in Multiplication Table
    658. Find K Closest Elements
    483. Smallest Good Base
    475. Heaters
    454. 4Sum II
    441. Arranging Coins
    436. Find Right Interval
    410. Split Array Largest Sum
    392. Is Subsequence
    378. Kth Smallest Element in a Sorted Matrix
  • 原文地址:https://www.cnblogs.com/riskyer/p/3243998.html
Copyright © 2011-2022 走看看