字典树-01字典树基础
生活随笔
收集整理的這篇文章主要介紹了
字典树-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字典树基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 停电了空调没关怎么办
- 下一篇: 可持久化-可持久化字典树