这几天在看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;
}
来源:CSDN
作者:MOGU漠沽
链接:https://blog.csdn.net/weixin_43925900/article/details/104169974