1. 程式人生 > >字首樹Trie

字首樹Trie

Trie樹(藍書P208寫的很詳細):

簡介: Trie樹(也叫字首樹).給你一個字典構成的Trie樹和一個單詞,我們可以線性的查找出該單詞是否屬於字典.

 

程式碼實現:

const int maxnode=4000*100+100;//預計字典樹最大節點數目
const int sigma_size=26;//每個節點的最多兒子數
 
struct Trie
{
    //這裡ch用vector<26元素的陣列> ch;實現的話,可以做到動態記憶體
    int ch[maxnode][sigma_size];//ch[i][j]==k表示第i個節點的第j個兒子是節點k
    int val[maxnode];//val[i]==x表示第i個節點的權值為x
    int sz;//字典樹一共有sz個節點,從0到sz-1標號
 
    //初始化
    void clear()
    {
        sz=1;
        memset(ch[0],0,sizeof(ch[0]));//ch值為0表示沒有兒子
    }
 
    //返回字元c應該對應的兒子編號
    int idx(char c)
    {
        return c-'a';
    }
 
    //在字典樹中插入單詞s,但是如果已經存在s單詞會重複插入且覆蓋權值
    //所以執行insert前需要判斷一下是否已經存在s單詞了
    void insert(char *s)
    {
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++)
        {
            int id=idx(s[i]);
            if(ch[u][id]==0)//無該兒子
            {
                ch[u][id]=sz;
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz++]=0;
            }
            u=ch[u][id];
        }
        val[u]=n;//這裡權值是長度,具體的權值要結合題目來
    }
 
    //在字典樹中查詢單詞s
    bool search(char *s)
    {
        int n=strlen(s),u=0;
        for(int i=0;i<n;i++)
        {
            int id=idx(s[i]);
            if(ch[u][id]==0)
                return false;
            u=ch[u][id];
        }
        return val[u];
    }
};