字典樹(trie)——楊子曰數據結構

字典樹(trie)——楊子曰數據結構

先扔一道題:HDU - 1251統計難題
就是說給你一堆字符串,再是一堆詢問,問你以這個字符串爲前綴的字符串有多少個?


今天我們來曰一個字符串中常用的數據結構——字典樹(高雅的人稱之爲trie樹(讀作:踹樹))
trie樹有一下幾個特點:
1.根節點是空的
2.每個節點上都會記錄一個字符(除了根節點)
3.從根節點下面出發,往下走路徑上記錄字符串,So,兩個串相同的前綴是它們後綴的公共祖先
我都覺得我沒有講清楚,相信你也一臉懵逼,於是我們來搞一個例子:
假設我們要把一下字符串放進trie:

aab
ab
abbc
abba
ac
bbb
bbc
ba
bac
cca

我們可以得到這樣一棵trie樹:
藍色的節點表示這個節點是一個字符串的結尾,也就是從根到藍色節點的路徑上是是一個串
這裏寫圖片描述
只要你是地球人就能秒懂
那我們怎麼建樹呢?,可以說是非常滴簡單呀!!直接上代碼:

                                      //tr[k][p]表示節點k的字符爲p的兒子的編號
void build(string s){                 //我們要把s放進trie裏
	int k=1;                          //根節點是1,我們現在在k節點
	for (int i=0;s[i];i++){
		int p=s[i]-'a';
		if (!tr[k][p]) tr[k][p]=++sum;//如果這個節點不存在,那就建一個,並把當前節點的這條邊指向它
		k=tr[k][p];                   //繼續往下走
	}
}

很顯然trie能解決的問題都和前綴有很大關係,解決問題時我們要考慮在trie上是否要記錄東西?記錄什麼東西?
這些東西可以是:這個節點是不是一個串的結尾,這個節點經過了幾次……(我也一時半會兒舉不出,尷尬)
到現在爲止,我們會發現上面那個問題會變得灰常簡單了,我們要在每個節點記錄它在建樹是時經過的次數,也就是所有字符串中,以根節點到這個節點路徑上的字符串爲前綴的字符串個數(←,很繞,自己模擬一下)
Then,對於每次查詢我們從根出發,找到這個字符串末尾的節點,輸出節點上記錄的值就歐了。
代碼走起:

int find(char *s){
	int k=1;
	for (int i=0;s[i];i++){
		int p=s[i]-'a';
		if (!tr[k][p]) return 0;//這個前綴不存在
		k=tr[k][p];
	}
	return num[k];
}

總結一波:建樹複雜度O(n|s|),查詢複雜度O(|s|),可以說是非常優啊!
OK,完事


c++代碼:

#include<cstdio>
#include<iostream>
using namespace std;

char s[100];
int sum=1;
int tr[500005][30],num[500005];

void build(char *s){
	int k=1;
	for (int i=0;s[i];i++){
		int p=s[i]-'a';
		if (!tr[k][p]) tr[k][p]=++sum;
		k=tr[k][p];
		num[k]++;
	}
}

int find(char *s){
	int k=1;
	for (int i=0;s[i];i++){
		int p=s[i]-'a';
		if (!tr[k][p]) return 0;
		k=tr[k][p];
	}
	return num[k];
}

int main(){
	while(gets(s) && s[0]) build(s);
	while(~scanf("%s",&s)){
		cout<<find(s)<<endl;
	}
	return 0;
}

注意:
對於有些題目,你要考慮把哪些字符串放進trie,推薦一道題:POJ - 1204 Word Puzzles
你以爲字典樹只能解決字符串的問題嗎?推薦一道題:[HDU 4825 - Xor Sum]
(https://blog.csdn.net/HenryYang2018/article/details/81452474)


如果你還知道一個東西叫KMP的話(不知道,
字典樹是媽媽,KMP是爸爸,會有一個小孩紙叫做AC自動機(注意!不是自動AC機,他們有本質區別)
戳我學習自動AC AC自動機
他是一個用KMP的想法在trie樹上實現的算法

於XJ機房607

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章