zoukankan      html  css  js  c++  java
  • 并不对劲的trie树

     听上去像是破坏植物的暴力行为(并不)。

    可以快速查询某个字符串在某个字符串集中出现了几次,而且听上去比字符串哈希靠谱。

    把整个字符串集建成树,边权是字符,对于字符串结尾的节点进行特殊标记。

    这样一方面合并了前缀,节省空间;另一方面查询很方便,直接按边走就行。

    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define maxn 10010
    #define maxk maxn*50
    #define maxm 30
    #define maxb 110010
    using namespace std;
    int read(){
        int f=1,x=0;char ch=getchar();
        while(isdigit(ch)==0 && ch!='-')ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    void write(int x){
        int ff=0;char ch[15];
        while(x)ch[++ff]=(x%10)+'0',x/=10;
        if(ff==0)putchar('0');
        while(ff)putchar(ch[ff--]);
        putchar(' ');
    }
    struct AC{
        int cnt,len,to[maxk][maxm],n,val[maxk],m;
        bool yes[maxk];
        char s[60];
        int getnum(char c){
            return int(c-'a');
        }
        void build(){
            int u=0,cur=0;
            for(;u<len;u++){
                if(!to[cur][getnum(s[u])])
                    to[cur][getnum(s[u])]=++cnt;
                cur=to[cur][getnum(s[u])];
            }
            val[cur]++,yes[cur]=1;
            return ;
        }
        void getans(){
            int u=0,cur=0;
            for(;u<len;u++){
                if(!to[cur][getnum(s[u])])
                    {printf("WRONG
    ");return;}        
                cur=to[cur][getnum(s[u])];
            }
            if(yes[cur]==0)printf("WRONG
    ");
            else if(val[cur]==0)printf("REPEAT
    ");
            else {val[cur]--;printf("OK
    ");} 
            return;
        }
        void prt(){
            for(int i=0;i<=cnt;i++){
                for(int j=0;j<=25;j++){
                    write(to[i][j]);
                }
                cout<<endl;
            }
        }
        void init(){
            cnt=0;
            n=read();
            for(int i=1;i<=n;i++){
                scanf("%s",s);
                len=strlen(s);
                build();
            }
        //    prt();
        }
        void ask(){
            m=read();
            for(int i=1;i<=m;i++){
                scanf("%s",s);
                len=strlen(s);
                getans();
            }
        }
    }solve;
    int main(){
        solve.init();
        solve.ask();
        return 0;
    }
    并不对劲的trie

    其实这是AC代码

    知道了这些又有什么用呢?某些字符串问题就能在树上乱搞了。

  • 相关阅读:
    Shell 丢弃错误和输出信息
    awk 循环过滤EPC脚本
    Tornado 异步浅解
    返回顶部
    Tornado 的安全性保障机制Cookie XSRF跨站请求伪造阻断 &用户验证机制
    Nginxre quest_time 和upstream_response_time
    Tornado WEB服务器框架 Epoll-- 【Mysql数据库】
    Tornado WEB服务器框架 Epoll-- 【模板】
    常见的SQL等价改写
    redis配置信息详解
  • 原文地址:https://www.cnblogs.com/xzyf/p/8244512.html
Copyright © 2011-2022 走看看