1. 程式人生 > >字典樹 | 數據結構

字典樹 | 數據結構

輸出 屬於 problem name int inf 開始 node ace

# 1 字典樹的概念

字典樹,是一種樹形結構,是一種哈希樹的變種。(來自度娘百科)

首先,字典樹的每一個節點都是長這樣的:

struct node{
    int end,son[27];
}a[maxn]

每個節點都有一個判斷自己是多少個單詞結尾的end與它之後的節點son[27]。

# 2 如何構造字典樹

假設我們輸入:

7

b

ab

ba

bb

aab

baa

aba

我們會得到一個這樣的結果:

技術分享圖片

我們可以輕松地找出每個節點的end值,如下:

技術分享圖片

這樣,我們就成功構建了一棵字典樹!

# 3 例題

例題 閱讀理解

分析:

step1: 我們將每一篇文章中的每一個單詞,用字典樹的方式存儲,記得標上自己是屬於哪一篇文章的。

step2: 對於每一個需要查詢的單詞,從根節點開始,不斷向下遍歷,如果在單詞的結尾剛好有一篇文章的一個單詞結尾在這裏,輸出文章號就OK了。

代碼(很久以前的代碼,碼風還OK,不過沒有用上文的方式存儲):

#include<bits/stdc++.h>
using namespace std;
int n,q,t,sum,son[500005][27];
bitset<1005> ans[500005];
map<string,int>m;
string str;
void change(int x,string s){
	int tmp=0;
	for(int j=0;j<s.size();tmp=son[tmp][s[j++]-96])
		if(son[tmp][s[j]-96]==0)
			son[tmp][s[j]-96]=++sum;
	m[s]=tmp;
	ans[tmp][x]=true;
}
void query(string s){
	if(m.count(s)){
		int num=m[s];
		for(int j=1;j<=n;++j)
			if(ans[num][j]==true)
				printf("%d ",j);
	}
	puts("");
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&t);
		for(int j=1;j<=t;++j){
			cin>>str;
			change(i,str);
		}
	}
	scanf("%d",&q);
	for(int i=1;i<=q;++i){
		cin>>str;
		query(str);
	}
	return 0;
}

字典樹 | 數據結構