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代码

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

  • 相关阅读:
    字符串_操作
    Error: Cannot find module 'webpack-cli/bin/config-yargs'
    ElementUI-Table 表头无法编辑问题
    ElementUI-Cascader组件同时支持懒加载和选择任意一级 问题踩坑
    vue强制刷新子组件
    footer部分,当页面主题内容不满一屏时,始终位于页面底部
    未知宽高的元素水平垂直居中方法总结
    fix元素居中
    link和@import引入css的区别
    Jquery拓展方法
  • 原文地址:https://www.cnblogs.com/xzyf/p/8244512.html
Copyright © 2011-2022 走看看