字典樹(Trie Tree)
php
題目描述ios
Ignatius最近遇到一個難題,老師交給他不少單詞(只有小寫字母組成,不會有重複的單詞出現),如今老師要他統計出以某個字符串爲前綴的單詞數量(單詞自己也是本身的前綴).網絡
輸入格式數據結構
輸入數據的第一部分是一張單詞表,每行一個單詞,單詞的長度不超過10,它們表明的是老師交給Ignatius統計的單詞,一個空行表明單詞表的結束.第二部分是一連串的提問,每行一個提問,每一個提問都是一個字符串.學習
注意:本題只有一組測試數據,處理到文件結束.測試
輸出格式spa
對於每一個提問,給出以該字符串爲前綴的單詞的數量..net
輸入樣例code
bananabandbeeabsoluteacmbabbandabc輸出樣例
2310
前不久學的Trie樹,主要參考自這個巨佬的博客:Trie樹傻瓜式入門+板子+經典例題
亂寫一通筆記。
Trie樹也叫字典樹,又稱單詞查找樹,是一種樹形的數據結構,是哈希樹的變種。主要運用於統計、排序和保存大量的字符串(但不只限於字符串)。
它的優勢是:利用字符串的公共前綴來減小查詢時間,最大限度地減小無謂的字符串比較,查詢效率比哈希樹高。
它主要長這樣:
(下圖爲插入了字符串at、bee、ben、bt、q後的Trie樹)
從這幅圖裏能夠看出,Trie樹的根節點是不包括字符的。也能夠看出Trie樹的主要思想。
代碼(結合hduoj的例題使用):
#include <cstdio> #include <iostream> #include <cstring> #include <string> using namespace std; const int maxn=1e6+10; char s[maxn]; struct Trie{ int next[27]; int cnt; void init(){ cnt=0; memset(next,-1,sizeof next); } }node[maxn]; int qwq=1; void Insert(string s){ int p=0; for (int i=0;i<s.size();i++){ int temp=s[i]-'a'; if (node[p].next[temp]==-1){ //不存在該節點,則新建節點 node[qwq].init(); node[p].next[temp]=qwq; qwq++; //後移一位,指向下一個未知的節點 } p=node[p].next[temp]; //向下走,走到目前搜到的最後一個節點 node[p].cnt++; } } void query(string s){ //查詢 int p=0; for (int i=0;i<s.size();i++){ int temp=s[i]-'a'; if (node[p].next[temp]==-1){ //不存在具備該前綴的字符串 printf("0\n"); return ; } p=node[p].next[temp]; } printf("%d\n",node[p].cnt); } int main(){ // freopen("test1.in","r",stdin); node[0].init(); string s; while (getline(cin,s)) if (s.size()==0) break; else Insert(s); while (getline(cin,s)) query(s); return 0; }
[學習自百度百科和其餘網絡資料]