字典樹(Trie樹)

字典樹(Trie Tree)
php

入門模板題 hdu oj P1251node

題目ios

  Ignatius最近遇到一個難題,老師交給他不少單詞(只有小寫字母組成,不會有重複的單詞出現),如今老師要他統計出以某個字符串爲前綴的單詞數量(單詞自己也是本身的前綴).網絡

輸入格式數據結構

  輸入數據的第一部分是一張單詞表,每行一個單詞,單詞的長度不超過10,它們表明的是老師交給Ignatius統計的單詞,一個空行表明單詞表的結束.第二部分是一連串的提問,每行一個提問,每一個提問都是一個字符串.學習

  注意:本題只有一組測試數據,處理到文件結束.測試

輸出格式spa

  對於每一個提問,給出以該字符串爲前綴的單詞的數量..net

輸入樣例code

banana
band
bee
absolute
acm
 
 
ba
b
band
abc

輸出樣例

2
3
1
0

 

  前不久學的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;
}

 

 

[學習自百度百科和其餘網絡資料]

相關文章
相關標籤/搜索