日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于Trie的一些算法

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于Trie的一些算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近學(xué)習(xí)了一下關(guān)于Trie的一些姿勢,感覺很實(shí)用。

終于不用每次看到字符串判重等操作就只想到hash

關(guān)于Trie的定義,來自百度百科

在計算機(jī)科學(xué)中,Trie,又稱前綴樹或字典樹,是一種有序樹狀的數(shù)據(jù)結(jié)構(gòu),用于保存關(guān)聯(lián)數(shù)組,其中的鍵通常是字符串。

說的有點(diǎn)高級,我們不要管它,可以看這樣一張圖:

這棵Trie中的單詞共有:his,he,her,me,your

就是從根節(jié)點(diǎn)一直到某個有end(結(jié)尾)標(biāo)記的點(diǎn)

可以發(fā)現(xiàn),Tire其實(shí)就是把一些字符串的公用前綴字符存儲了下來

Tire的實(shí)現(xiàn)更是簡單:

  • 建立一棵Trie,初始時只有一個空的根節(jié)點(diǎn)(編號為0)

  • 每當(dāng)插入或刪除時,如果當(dāng)前字符在之前的操作中已經(jīng)建立,然后直接利用即可,否則新建立一個節(jié)點(diǎn)并讓上一個節(jié)點(diǎn)連上它

  • 當(dāng)一個字符串結(jié)束時,給該節(jié)點(diǎn)做個記號,同時也可存儲些其它的信息

  • 具體的實(shí)現(xiàn)方法也有兩種:鄰接表鄰接矩陣

    在Trie中,顯然用鄰接矩陣是很快的,但空間的開銷可能較大,如果題目說明范圍,那么空間允許的情況下可以使用

    鄰接表還是一樣,比較省空間(畢竟要多少開多少)

    這里用一道板子題來理解一下:

    hihocoder 1366 : 逆序單詞

    鄰接矩陣CODE

    #include<iostream> #include<string> using namespace std; const int N=50005; struct node {bool end;int next[30]; }trie[N<<4]; string s; int n,ans,cnt; inline bool find(string s) {int now=0,len=s.size();for (register int i=0;i<len;++i){if (trie[now].next[s[i]-'a'+1]) now=trie[now].next[s[i]-'a'+1]; else return 0;if (i==len-1) return trie[now].end;} } inline void insert(string s) {int now=0,len=s.size();for (register int i=0;i<len;++i){if (trie[now].next[s[i]-'a'+1]) now=trie[now].next[s[i]-'a'+1]; else trie[now].next[s[i]-'a'+1]=++cnt,now=cnt;if (i==len-1) trie[now].end=1;} } int main() {register int i;for (cin>>n,i=1;i<=n;++i){cin>>s;string rs(s.rbegin(),s.rend());if (find(rs)) ++ans;insert(s);}cout<<ans;return 0; }

    鄰接表CODE

    #include<iostream> #include<cstring> #include<string> using namespace std; const int N=50005; struct node {bool end;char ch; }trie[N<<4]; struct edge {int to,next; }link[N<<4]; string s; int head[N<<4],n,ans,cnt; inline void add(int x,int y,char z) {link[y].to=y; trie[y].ch=z; link[y].next=head[x]; head[x]=y; } inline bool find(string s) {int now=0,len=s.size();for (register int i=0;i<len;++i){bool flag=0;for (register int j=head[now];j!=-1;j=link[j].next)if (trie[link[j].to].ch==s[i]) { flag=1; now=link[j].to; break; }if (!flag) return 0;if (i==len-1) return trie[now].end;} } inline void insert(string s) {int now=0,len=s.size();for (register int i=0;i<len;++i){bool flag=0;for (register int j=head[now];j!=-1;j=link[j].next)if (trie[link[j].to].ch==s[i]) { flag=1; now=link[j].to; break; }if (!flag) add(now,++cnt,s[i]),now=cnt;if (i==len-1) trie[now].end=1;} } int main() {register int i;memset(link,-1,sizeof(link));memset(head,-1,sizeof(head));for (cin>>n,i=1;i<=n;++i){cin>>s;string rs(s.rbegin(),s.rend());if (find(rs)) ++ans;insert(s);}cout<<ans;return 0; }

    轉(zhuǎn)載于:https://www.cnblogs.com/cjjsb/p/8835042.html

    總結(jié)

    以上是生活随笔為你收集整理的关于Trie的一些算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。