字典树

\(Trie\)

基本概念:

\(trie\) 主要是用来存放字符串的,每一个节点表示一个字符,每个 \(node\) 都表示一个根节点.

就像这样:插入 \(see,pain,pand,dog,trie\) (可以得出一个性质就是如果全是小写字母,每个根节点最多有\(26\)个根节点)

相关代码:

#include<bits/stdc++.h>
using namespace std;
char str[10005][15];//读入
int trie[10005][26],tot=1;
bool end[10005];
void insert(char* str){
	int len=strlen(str),p=1;
	for(int k=0;k<len;k++){
		int ch=str[k]-'a';
		if(trie[p][ch]==0)
			trie[p][ch]=++tot;//做标记
		p=trie[p][ch];//p指向地址
	}
	end[p]=true;//这个单词被读入过
}
bool search(char *str){
	int len=strlen(str),p=1;
	for(int k=0;k<len;k++){
		p=trie[p][str[k]-'a'];//遍历搜索
		if(p==0)
			return false;//不存在
	}
	return true;//存在,为子串
}
int main(){
	int n;
	cin>>n;
	memset(end,false,sizeof(end));
	for(int i=1;i<=n;i++)	{
		cin>>str[i];
		insert(str[i]);
	}	
	search();//未写完	
	return 0;
}

其中,\(p\) 作为指针起初指向根节点,扫描 \(str\) 中的每一个字符 \(c\) :

  1. \(p\)\(c\) 字符指针指向一个已经存在的节点 \(q\) ,则令 \(p=q\)

  2. \(p\)\(c\) 字符指向为空,则新建一个节点 \(q\),令 \(q\)\(c\) 字符指向 \(q\) ,然后令 \(p=q\);

\(str\) 中的每一个字符都扫描完毕时,在节点 \(p\) 上标记它是一个字符串的末尾。

用处:

  1. 多条字符串读入比较

  2. 运用于后缀数组,后缀自动机

posted @ 2021-10-10 11:27  Evitagen  阅读(35)  评论(0编辑  收藏  举报