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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字典树-01字典树基础

發布時間:2023/12/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字典树-01字典树基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字典樹-01字典樹

什么是字典樹?

字典樹,又叫前綴樹,Trie樹,通常被用作字符串匹配。

它的實現原理是什么?

先建立一顆樹,對于這棵樹上每個節點i與其后繼節點間的連線,都有存入一個字符。

對于存圖時,從0節點開始遍歷,找到其與其他出現過的字符第前綴不同的地方,新增節點。代碼如下:

int p = 0, k = 0; for(int i = 0; i < str.length(); i++){int t = str[i] - 'a';if(!st[p][t]) st[p][t] = k++;p = st[p][t]; }

以上代碼,p為當前節點編號,k為新增節點編號。當查找到有不同的字符,由p指向t,新增節點k,k自增1作為下一節點,并將p更新到新增節點,以便后續字符的添加。

對于查詢,則是相同的思路。代碼如下:

int p = 0; for(int i = 0; i < s.length(); i++){if(!st[p][s[i] - 'a'])return -1;p=st[p][s[i] - 'a']; } return 1;

若出現的字符不存在樹中,直接返回-1,代表查詢失敗。全部查詢結束,代表查詢成功,返回1.

模板樣例:

輸入n,m,分別為字符串數量與查詢字符串數量,接下來m+n行字符串

輸出m行,若存在則輸出"存在",否則輸出"不存在".

輸入樣例

5 3 abccc jcjcj abaca kacbd kacbdaa abc aba abd

輸出樣例

存在 存在 不存在

代碼

#include<iostream> #include<algorithm> #include<stdio.h> #include<string> #include<string.h>using namespace std;int st[1005][30]; string str; int k = 1;void sett(string str) {int p = 0;for (int i = 0; i < str.length(); i++) {int t = str[i] - 'a' + 1;if (!st[p][t]) st[p][t] = k++;p = st[p][t];} }bool seac() {cin >> str;int p = 0;for (int i = 0; i < str.length(); i++) {int t = str[i] - 'a' + 1;if (!st[p][t]) return false;p = st[p][t];}return true; }int main() {int n, m;cin >> n >> m;while (n--) {cin >> str;sett(str);}while (m--) {if (seac())cout << "存在\n";else cout << "不存在\n";}return 0; }

什么是01字典樹?

01字典樹主要解決異或最值問題。

算法原理

同trie一樣,將其中的字符轉為0或1即可。

存圖

int p = 0; for(int i = 32; i >= 0; i--){int t = (x >> i) & 1;if(!st[p][t]) st[p][t]=k++;p = st[p][t]; } val[p]=x;

存圖時,從為高位,每個鏈都有32層,是一個完全二叉樹,以方便查詢時對異或查找的便捷。

注:雖然圖為32層,但是加入的節點(可查詢節點的數量)只有你輸入數字二進制為1的數量。因此不必擔心查詢過慢的問題。

查詢

int p = 0; for(int i = 32; i >= 0; i--){int t = (x >> i) & 1;if(!st[p][t]) p = st[p][t];//此處是根據計算異或的最大或最小值,按照貪心方法計算,若最大,優先找不同的點,反之則反else p = st[p][t ^ 1]; } return val[p];

代碼

#include<iostream> #include<algorithm> #include<stdio.h> #include<string> #include<string.h> typedef long long ll;using namespace std;int k = 1; int st[10005][2]; int val[10005];void insert(int x){int p = 0;for(int i = 32; i >= 0; i--){int t = (x >> i) & 1;if(!st[p][t]) st[p][t]=k++;p = st[p][t];}val[p]=x; }int seacher(int x){int p = 0;for(int i = 32; i >= 0; i--){int t = (x >> i) & 1;if(st[p][t ^ 1]) p = st[p][t ^ 1];else p = st[p][t];}return val[p]; }int main() {int n;cin>>n;while(n--){int a;cin>>a;insert(a);}int num;cin>>num;cout<<(seacher(num)^num)<<endl;return 0; }

總結

以上是生活随笔為你收集整理的字典树-01字典树基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。