zoukankan      html  css  js  c++  java
  • HDU2222

    http://acm.hdu.edu.cn/showproblem.php?pid=2222

    注意:

    1. keyword可以相同,因此计算时要累计:cur->num++。

    2. 同一个keyword在str中出现多次的话,只计算一次,所以算过后需要将num设为-1(表示已经计算了)。

    对于

    2
    5
    she
    he
    say
    shr
    her
    yasherhs
    5
    she
    he
    say
    sher
    her
    yasherhs

    sher中包含:she,he,her,sher四个关键字,计算顺序:she->he->e->sher->her。

    注意:匹配到一个关键字,需要继续把这个keyword中包含的其他的短的keyword都匹配了,再继续前移。

    # include <cstdio>
    #include <stdlib.h>
    #include "memory.h"
    #include "queue"
    
    const int MAX_N = 1000010;
    
    char s[MAX_N];
    
    struct TNode {
        int num;
        TNode *suffix;
        TNode *next[26];
        TNode() {
            clean();
        }
        void clean() {
            num = 0;
            suffix = NULL;
            memset(next, NULL, sizeof next);
        }
    };
    
    TNode *T[MAX_N];
    
    int pos = 0;
    
    void buildTrie(char *str) {
        TNode * cur = T[0];
        for (int i = 0; str[i]; ++i) {
            int c = str[i] - 'a';
            if (cur->next[c] == NULL) {
                if (T[++pos] == NULL) {
                    T[++pos] = new TNode();
                }
                cur->next[c] = T[pos];
            }
            cur = cur->next[c];
        }
        cur->num++;
    }
    
    void addSuffix() {
        TNode* root = T[0];
        root->suffix = root;
        std::queue<TNode*> qTrie;
        for (int i = 0; i < 26; ++i) {
            if (root->next[i] == NULL) {
                root->next[i] = root;
            } else {
                root->next[i]->suffix = root;
                qTrie.push(root->next[i]);
            }
        }
        TNode *cur, *suf;
        while (!qTrie.empty()) {
            cur = qTrie.front(), qTrie.pop();
            suf = cur->suffix;
            for (int i = 0; i < 26; ++i) {
                if (cur->next[i] == NULL) {
                    cur->next[i] = suf->next[i];
                } else {
                    cur->next[i]->suffix = suf->next[i];
                    qTrie.push(cur->next[i]);
                }
            }
        }
    }
    
    int query(char *str) {
        int ans = 0;
        TNode * cur = T[0];
        for (int i = 0; str[i]; ++i) {
            int c = str[i] - 'a';
            cur = cur->next[c];
            TNode * back = cur;
    
            while (back != T[0] && back->num != -1) {
    //            printf("%c %d
    ", str[i], back->num);
                ans += back->num;
                back->num = -1;
                back = back->suffix;
            }
        }
        return ans;
    }
    
    void clean() {
        for (int i = 0; i <= pos; ++i) {
            if (T[i] != NULL) {
                T[i]->clean();
            }
        }
        pos = 0;
    }
    
    
    int main() {
        if (freopen("/Users/fripside/ClionProjects/cc150/input", "r", stdin) == NULL) {
            fprintf(stderr, "error redirecting stdout
    ");
        }
        T[0] = new TNode;
        int c, t;
        scanf("%d", &c);
        while (c--) {
            clean();
            scanf("%d", &t);
            while (t--) {
                scanf("%s", s);
                buildTrie(s);
            }
            addSuffix();
            scanf("%s", s);
            printf("%d
    ", query(s));
        }
        return 0;
    }
    

      

  • 相关阅读:
    高斯消元
    丑数
    扩展欧几里得算法与线性同余方程
    数论-求逆元
    数论-快速幂-快速乘
    宋逸轩长难句 2
    宋逸轩长难句 1
    c语言 文件
    c语言程序结构
    c语言结构类型
  • 原文地址:https://www.cnblogs.com/fripside/p/5226773.html
Copyright © 2011-2022 走看看