数据结构-字符串-字典树

数据结构-字符串-字典树

字典树就是著名的 t r i e trie 树,是未来学很多字符串自动机的必备前置知识。

用处:插入字符串,查找字符串出现次数。

这个数据结构就是一个有根树,根节点编号为 1 1 。除了根节点外,每个节点上有一个字母。对于每个节点 x x c h [ x ] [ c ] ch[x][c] 表示这个节点的儿子中字符为 c c 的那个的编号, m k [ x ] mk[x] 表示插入的字符串中以这个节点为结尾的字符串数。

每当要插入一个字符串 s s (下标从 1 1 开始)时,就从根节点 1 1 开始,如果根节点 1 1 没有字符为 s [ 1 ] s[1] 的子节点,就创造一个那个节点,然后无论那个节点是不是刚被创造出来的,走到那个节点。然后再看那个节点有没有字符为 s [ 2 ] s[2] 的子节点,然后如此操作,走到 s [ n ] s[n] (字符串长度为 n n )时, m k [ mk[ 单前节点 ] + + ]++

查找字符串 s s 时,也从根节点 1 1 开始,沿着 c h [ ] [ ] ch[][] 数组走,如果发现某次节点没有字符串 s s 的单前字符子节点,那么久说明字符串 s s 以前没有出现过。否则,走到 s [ n ] s[n] 时,可得 s s 字符串出现的次数就为 m k [ mk[ 单前节点 ] ]

For   example: \texttt{For example:}

如果我们插入了这些字符串:
wa \texttt{wa}
wen \texttt{wen}
we \texttt{we}
ha \texttt{ha}
那么字典树就长这样(黄色数字为节点的 m k [ ] mk[] ,没有黄色数字表示 m k [ ] mk[] 0 0 ):
zds.jpg
由于字符的种类只有 a z a\sim z ,而且正常英文单词的长度不会超过 30 30 ,所以可以保证字典树空间复杂度和时间复杂度不超标,每次插入查询都是 O ( 1 ) O(1) 的。

如果你已经掌握了这些知识,那么蒟蒻就放代码了:

class trie{
public:
	int ch[N][30],cnt,mk[N];
	trie(){cnt=1;}
	void insert(char*s){
		int n=strlen(s+1),x=1;
		for(int i=1;i<=n;i++){
			int c=s[i]-'a'+1;
			if(!ch[x][c]) ch[x][c]=++cnt;
			x=ch[x][c];
		}
		mk[x]++;
	}
	int find(char*s){
		int n=strlen(s+1),x=1;
		for(int i=1;i<=n;i++){
			int c=s[i]-'a'+1;
			if(!ch[x][c]) return 0;
			x=ch[x][c];
		}
		return mk[x];
	}	
}t;

学字符串道路:

hash-kmp-manacher-exkmp-trie-ac-sa-sam-pam \texttt{hash-kmp-manacher-exkmp-trie-ac-sa-sam-pam}

祝大家学习快乐!

发布了11 篇原创文章 · 获赞 24 · 访问量 633

猜你喜欢

转载自blog.csdn.net/KonnyWen/article/details/104220434