字典树 前缀树 trie

让人想犯罪 __ 提交于 2020-02-04 18:17:13

这几天在看AC自动机,发现AC自动机有个前置任务:掌握字典树。
字典树的原理其实就是储存并检索字符串的前缀。
实现过程其实就是用一个变量去储存树的下标,如果插入的字符串不停更新下标。


放一道模板题:P2580 于是他错误的点名开始了
AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
//#pragma GCC optimize(3,"Ofast","inline")
#define LL long long
#define MT(a,b) memset(a,b,sizeof(a))
const int mod=1000007;
const int maxn=500010;
const int ONF=-0x3f3f3f3f;
const int INF=0x3f3f3f3f;
int tot,trie[maxn][30];
char s[maxn];
bool vis[maxn];
void add(char *str){
    int len=strlen(str);
    for (int i=0,pos=0;i<len;i++){
        if (!trie[pos][str[i]-'a']) trie[pos][str[i]-'a']=++tot;
        pos=trie[pos][str[i]-'a'];
    }
}
int query(char *str){
    int len=strlen(str);
    int pos=0;
    for (int i=0;i<len;i++){
        if (trie[pos][str[i]-'a'])  pos=trie[pos][str[i]-'a'];
        else return -1;
    }
    if (vis[pos]== true) return 0;
    else {
        vis[pos]=true;
        return 1;}
}
void build_trie(int n){
    tot=0;
    MT(trie,0);
    for (int i=1;i<=n;i++){
        scanf("%s",s);
        add(s);
    }
}
void solve(int m){
    MT(vis, false);
    for (int i=1;i<=m;i++){
        scanf("%s",s);
        int k=query(s);
        if (k==-1) printf("WRONG\n");
        if (k==0) printf("REPEAT\n");
        if (k==1) printf("OK\n");
    }
}
int main (){
    int m,n;
    scanf("%d",&n);
    build_trie(n);
    scanf("%d",&m);
    solve(m);
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!