Trie學習總結

2022-05-25 12:48:12 字數 3407 閱讀 5739

字典樹,又稱字首樹,是用於快速處理字串的問題,能做到快速查詢到一些字串上的資訊。

另外,trie樹在實現高效的同時,會損耗更多的空間,所以trie是一種以空間換時間的演算法。

trie的思想十分簡單,其實我在很早之前就已經懂了trie的思想,只不過一直沒有實現,所以就……

咕咕,沒事,trie無論是思想還是**思想都還是很簡單。現在我重新再搞回trie也很快就**實現了。

trie是思想其實用圖更容易展現。下面放一張圖給大家看看,相信大家很快就會明白了。

如果我們插入字串:

上面就是一顆我們建的trie樹。

如果我們要查詢「zlh」,那麼就會沿著1->2->3點找下去。

如果我們要查詢「akioi」,那麼我們就會沿著4->5->9->10->11點找

也可以十分容易發現"ak"是"akioi"的字首。

那麼大家現在應該就能明白trie的構造了吧。

簡單說就是順著之前trie樹的構造去插入點,例如我們最後插入"aknoip",就會先走過"a"和"k",然後發現沒有匹配的字元了,就先後新建了'n','o','i','p',這幾個點。複雜度o(len(字串))。

查詢就會沿著trie的構造乙個乙個跳,所以查詢複雜度是o(len(字串))。

那麼trie的思想就是這樣了。

明白了思想,實現就應該很簡單了吧,這裡通過一道例題來實現trie。

題目:p2580 於是他錯誤的點名開始了

struct kkktrie[maxn];
void insert(string s)   //清0

}trie[400001];

int n,t,num;

string s[400001];

void insert(string s)

bool ans=false;

for(int i=1;i<=n;i++) //判斷是不是字首

}if(ans==true)printf("no\n"); //輸出

else printf("yes\n");}}

題目:immediate decodability

這道題和上面那道題一模一樣,不過輸入比較噁心,而且資料範圍也比較小。

這裡的輸入就是不斷輸入字串s,然後將字串s插入到trie中,直到s='9'為止。

到了s='9',就將之前的s都像上面的一樣查詢一邊,輸出答案,然後清0。

**:

#includeusing namespace std;

struct kkk

}trie[2001];

int n,t,num,t;

string s[400001];

void insert(string s)

insert(s[n]);n++; //如果不是『9』就插入}}

題目:the xor largest pair

這道題是一道變向的trie,也是trie的乙個基本應用。

思路:1、首先將a[i]轉換為二進位制的字串存起來,記得空位要補0

2、然後將這些字串都插入到trie裡。

3、查詢每乙個字串,找到以每乙個數和另外其他數的最大異或和。

那麼問題就是怎麼找乙個數和另外其他數的最大異或和了。

我們知道,異或是不同就為1,相同就為0,所以我們因盡量讓高位的二進位制為1。

所以我們查詢的時候就倒著查,也就是如果s[i]為0,那麼我們就查1。但是沒有1怎麼辦,我們總不能就此放棄吧,於是我們繼續查0。

最後取個最大值就ok了。

看看**:

#includeusing namespace std;

struct kkk

}trie[4000001];

int n,t,num,ans;

int x[1000001];

void insert(string s)

int main()

for(int i=1;i<=n;i++)

printf("%d\n",ans);

}

題目大意:給你n個資訊和m個密碼,要你求出對於每乙個密碼都多少資訊,使這些資訊的字首和密碼的字首相同。

理解清題目,這道題就很簡單了,我們用資訊來在建立trie時多維護乙個資料sum,存的是有多少個資訊經過這個節點。那麼我們在查詢時,先統計有多少資訊是密碼的字首再加上當前節點的sum就是答案。

#includeusing namespace std;

struct kkk

}trie[400001];

int n,t,num,ans;

string s[400001];

void insert(string s)

for(int i=1;i<=m;i++)

}

題目在這裡:「一本通 2.3 例 3」nikitosh 和異或

首先對於如何求異或最大值我們已經在上文學到了,現在我們要求的是兩個沒有覆蓋的區間異或的和。

異或有乙個性質:就是據有可減性,也就是說我們記字首異或sum陣列,如果求[l,r]的異或和,那麼答案就是sum[r]^sum[l-1];字尾異或也是一樣的

所以我們可以對於每乙個位置i都求一遍以i為結尾的區間中,最大的區間異或值。方法是將i前面的每乙個字首sum陣列都插入到trie中,然後find(sum[i]),答案計為l陣列

另外,對於每乙個位置i都求一遍以i為開頭的區間中,最大的區間異或值。方法是將i後面的每乙個字尾sum陣列都插入到trie中,然後find(sum[i]),答案計為r陣列

那麼對於每乙個位置i,都統計前面的最大的l,記錄下來。表示的是i前面的最大區間異或和

對於每乙個位置i,都統計後面的最大的r,記錄下來。表示的是i後面的最大區間異或和

那麼答案就是對於每乙個位置i的 前面的最大區間異或和 和 後面的最大區間異或和 的 和 的最大值

**:

#includeusing namespace std;

struct kkk

}trie[8000001];

int n,t,num,ans;

int x[1000001],l[1000001],r[1000001],s[35];

void insert(int x)

for(int i=31;i>=0;i--)

}int find(int x)

trie樹學習總結(字典樹模板)

trie樹 演算法簡介 字典樹,也叫trie樹,是一種比較實用的資料結構,無論是在acm競賽的題目中,還是字串相關的某些實際應用領域內,它都能發揮巨大的作用。首先來看看字典樹的本質是什麼。它其實是一棵儲存了很多字串的樹,這棵樹上的每一條邊就是某個或某些字串中的乙個字元,而從根節點到某乙個特定節點所經...

Trie 樹學習下

今天把trie樹徹底的看了下。發現網上有兩篇非常好的文章,通過他們的部落格,我對trie樹有了大題的了解。並且通過理解 消化 綜合他們的知識,再結合我自己的程式設計愛好,我也把具體的程式實現了一遍,這樣能對trie樹有更加深刻的認識!他們是 勇幸 thinking 和 maik 感謝他們。下面的分析...

Trie樹的學習

所寫內容,是對自己所學知識的乙個記錄罷了。1.簡介 最近在做中國人名識別的時候,看到一篇文章是基於角色的人名識別,而角色字典中有2個角色是用雙陣列tire樹來建立的,當時沒有看懂,於是來先學習trie樹。trie樹,又稱字典樹,單詞查詢樹或者字首樹等,是一種快速 檢索的多叉樹結構。比如,英文本母的字...