• ZOJ 3228 Searching the String (AC自己主动机)


    题目链接:Searching the String


    解析:给一个长串。给n个不同种类的短串。问分别在能重叠下或者不能重叠下短串在长串中出现的次数。

    能重叠的已经是最简单的AC自己主动机模板题了。

    不能重叠的记录一下每一个匹配的串的起始位置保证不重叠就可以。



    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Trie{
        int next[600010][26], fail[600010], deep[600010];
        int root, L;
    
        int newnode(){
            for(int i = 0; i < 26; i++) next[L][i] = -1;
            L ++;
            return L-1;
        }
    
        void init(){
            L = 0;
            root = newnode();
            deep[root] = 0;
        }
    
        int insert(char buf[]){
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++){
                if(next[now][ buf[i] - 'a' ] == -1){
                    next[now][ buf[i] - 'a' ] = newnode();
                    deep[next[now][buf[i] - 'a']] = i+1;
                }
                now = next[now][ buf[i] - 'a' ];
            }
            return now;
        }
    
        void build(){
            queue<int> Q;
            fail[root] = root;
            for(int i = 0; i < 26; i++){
                if(next[root][i] == -1) next[root][i] = root;
                else{
                    fail[ next[root][i] ] = root;
                    Q.push(next[root][i]);
                }
            }
            while(!Q.empty()){
                int now = Q.front();
                Q.pop();
                for(int i = 0; i < 26; i++){
                    if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i];
                    else{
                        fail[ next[now][i] ] = next[ fail[now] ][i];
                        Q.push(next[now][i]);
                    }
                }
            }
        }
    
        int cnt[600010][2];   //cnt[][0]表示能重叠的,cnt[][1]表示不能重叠的
        int last[600010];    //上次匹配的字符
        void query(char buf[]){
            memset(cnt, 0, sizeof(cnt));
            memset(last, -1, sizeof(last));
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++){
                now = next[now][ buf[i] - 'a' ];
                int temp = now;
                while(temp != root){
                    cnt[temp][0] ++;
                    if(i - last[temp] >= deep[temp]){    //保证不重叠
                        last[temp] = i;
                        cnt[temp][1] ++;
                    }
                    temp = fail[temp];
                }
            }
        }
    };
    
    char buf[20];
    char str[100010];
    int typ[100010], pos[100010];
    Trie ac;
    
    int main(){
        #ifdef sxk
            freopen("in.txt", "r", stdin);
        #endif //sxk
    
        int n;
        int kase = 0;
        while(scanf("%s", str) == 1){
            scanf("%d", &n);
            ac.init();
            for(int i = 0; i < n; i++){
                scanf("%d%s", &typ[i], buf);
                pos[i] = ac.insert(buf);
            }
            ac.build();
            ac.query(str);
            printf("Case %d
    ", ++kase);
            for(int i=0; i<n; i++)
                printf("%d
    ", ac.cnt[pos[i]][typ[i]]);
            printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    HDU 2563 统计问题 (DFS + 打表)
    KendoUi中KendoDropDownList控件的使用——三级级联模块的实现
    POJ 1325 &amp;&amp; ZOJ 1364--Machine Schedule【二分图 &amp;&amp; 最小点覆盖数】
    crontab FAQ
    思科2960trunk vlan配置及路由IP配置
    hdoj-1593-find a way to escape【数学题】
    Java编程思想(四) —— 复用类
    在 Android 应用程序中使用 SQLite 数据库以及怎么用
    Swift Standard Library Reference.pdf
    VC、IE、ASP环境下打印、预备的完美解决方式
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7190571.html
Copyright © 2020-2023  润新知