并不对劲的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代码

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

原文地址:https://www.cnblogs.com/xzyf/p/8244512.html