[模板] Trie 树

[模板] Trie 树

听机房人说这是个特别简单的数据结构

于是他错误的点名开始了

\(Trie\) 树一般有两种操作(具体问题具体修改):

定义

  • 定义一个类似于邻接表的东西和初始节点

  • 其中 \(t\) 数组第二维表示 \(c\) 字符在当前节点指向的节点编号

int trie[maxn][26],cnt=1;

\(maxn\) 表示最长字符长度*字符个数

插入

void insert(char *s){
	int len=strlen(s),p=1;
	for(int k=0;k<len;k++){
		int ch=s[k]-'a';
		if(!trie[p][ch])trie[p][ch]=++cnt;//开点
		p=trie[p][ch];
	}
	end[p]=true;//记录每个位置是不是字符串的结尾,非常有必要
}

查询是否存在

bool find(char *s){
	int len=strlen(s),p=1;
	for(int k=0;k<len;k++){
		p=trie[p][s[k]-'a'];
		if(!p)return false;
	}
	return end[p];//end的用处
}

题解

对于此题而言,稍加修改即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
template <typename T>
inline T read(){
	T x=0;char ch=getchar();bool fl=false;
	while(!isdigit(ch)){if(ch=='-')fl=true;ch=getchar();}
	while(isdigit(ch)){
		x=(x<<3)+(x<<1)+(ch^48);ch=getchar();
	}
	return fl?-x:x;
}
const int maxn = 5e5 + 100;
int n,m;
#define LL long long
int t[maxn][26],cnt=1;
bool end[maxn],vis[maxn];
void insert(char *s){
	int len=strlen(s),p=1;
	for(int k=0;k<len;k++){
		int ch=s[k]-'a';
		if(!t[p][ch])t[p][ch]=++cnt;
		p=t[p][ch];
	}
	end[p]=true;
}
int search(char *s){
	int len=strlen(s),p=1;
	for(int k=0;k<len;k++){
		p=t[p][s[k]-'a'];
		if(!p)return 0;
	}
	if(!end[p])return 0;
	else{
		if(!vis[p]){vis[p]=true;return 1;}
		else if(vis[p])return 2;
	}
}
int main(){
	n=read<int>();
	while(n--){
		char ch[55];cin>>ch;
		insert(ch);
	}
	m=read<int>();
	while(m--){
		char ch[55];cin>>ch;
		int fl=search(ch);
		if(fl==0)puts("WRONG");
		else if(fl==1)puts("OK");
		else puts("REPEAT");
	}
	return 0;
}
上一篇:深度学习面试题10:二维卷积(Full卷积、Same卷积、Valid卷积、带深度的二维卷积)


下一篇:UVA12124 Assemble