1. 程式人生 > 實用技巧 >資料結構:字典樹模板

資料結構:字典樹模板

點選檢視程式碼塊
/*
trie樹(字首樹)
trie[maxnNode][charSet]
trie[i][j] == 0 表示trie樹中的第i號節點,沒有連邊
trie[i][j] == x 表示trie樹中的第i號節點,與樹中的第x號節點有一條連邊,邊權為字符集中的第j個字元 
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
const int charset = 30;
int trie[maxn][charset];
int tot;//trie中節點的個數 
int color[maxn]={0};
int a[maxn];

//insert的時間複雜度 :O(len(s)) 
void insert(char *s){//在字典樹中插入字串s 
	int len = strlen(s);
	int p = 0;//從根節點開始 
	for (int i=0;i<len;i++){
		int c=s[i]-'a';
		if(!trie[p][c]){//樹中沒有節點p向外連的邊權為c的邊 
			trie[p][c]=++tot;
		}
		a[trie[p][c]]++;
		p=trie[p][c];
	}
	color[p]=1;//標記最後的節點為p 
}

//search的時間複雜度 :O(len(s))
int search(char *s){//在字典樹中查詢s字串 
	int len=strlen(s);
	int p=0;
	for (int i=0;i<len;i++){
		int c = s[i]-'a';
		if(!trie[p][c]) return 0;//字元不匹配,找不到這樣的字串 
		p = trie[p][c];
	}
//	return color[p]=1;//如果p的color為1,表明到達了葉子節點,說明這樣的字串存在
	return a[p];
}

char ss[maxn];

int main(){
	while(gets(ss)){
		if(ss[0] == '\0') break;
		insert(ss);
	}
	while(cin>>ss){
		int ans = search(ss);
		printf("%d\n",ans);
	}
	return 0;
}