• 字符串--AC自动机


    终于过了一次,以前每次都错。。。
    我讲的不好,但是我找到一个讲的好的,大家看看:blog
    下来贴个代码:(洛谷 P3796)

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline int idx(char c){
        return c-'a';
    }
    int tot,ans;
    int ch[1000001][26];
    int f[1000001];
    int val[1000001];
    int last[1000001];
    int cnt[1000001];
    void insert(char* P,int v){
        int len=strlen(P);
        int u=0;
        for(int i=0;i<len;i++){
            int c=idx(P[i]);
            if(!ch[u][c]){
                ch[u][c]=++tot;
            }
            u=ch[u][c];
        }
        val[u]=v;
    }
    void getfail(){
        queue<int> q;
        q.push(0);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            int k=f[u];
            for(int c=0;c<26;c++){
                int v=ch[u][c];
                if(!v){
                    ch[u][c]=ch[k][c];
                    continue;
                }
                q.push(v);
                f[v]=u?ch[k][c]:0;
                last[v]=val[f[v]]?f[v]:last[f[v]];
            }
        }
    }
    void find(char* T){
        int n=strlen(T);
        int u=0;
        for(int i=0;i<n;i++){
            int c=idx(T[i]);
            u=ch[u][c];
            if(val[u]){
                cnt[u]++;
            }
            int v=u;
            while(last[v]){
                v=last[v];
                if(val[v]){
                    cnt[v]++;
                }
            }
        }
    }
    char P[151][71];
    char T[1000001];
    int main(){
        while(1){
            memset(ch,0,sizeof(ch));
            memset(val,0,sizeof(val));
            memset(f,0,sizeof(f));
            memset(last,0,sizeof(last));
            memset(cnt,0,sizeof(cnt));
            tot=0;
            ans=0;
            int n;
        scanf("%d",&n);
        if(n==0)break;
        for(int i=1;i<=n;i++){
            scanf("%s",P[i]);
            insert(P[i],i);
        }
        getfail();
        scanf("%s",T);
        find(T);
        int mx=0;
        for(int i=1;i<=tot;i++){
            mx=max(mx,cnt[i]);
        }
        printf("%d
    ",mx);
        for(int i=1;i<=tot;i++){
            if(cnt[i]==mx){
                printf("%s
    ",P[val[i]]);
            }
        }
        }
        return 0;
    }
  • 相关阅读:
    Linux信号列表(zz)
    TCP状态转移图学习总结
    UNP学习笔记之四select和poll
    RSS2.0结构
    UNP学习笔记二简单的并发服务器(concurrent servers)
    js面向对象基础(zz)
    libevent introduction
    Linux下Makefile的automake生成全攻略(zz)
    UNP学习笔记之三POSIX Signal Handling
    关于网络编程(服务端)的一些笔记(zz)
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581261.html
Copyright © 2020-2023  润新知