Tire樹(字典樹)

理論

在這里插入圖片描述
上圖是一棵Trie樹,表示了關鍵字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。從上圖可以歸納出Trie樹的基本性質:

  • 根節點不包含字符,除根節點外的每一個子節點都包含一個字符。
  • 從根節點到某一個節點,路徑上經過的字符連接起來,為該節點對應的字符串。
  • 每個節點的所有子節點包含的字符互不相同。
  • 從第一字符開始有連續重復的字符只占用一個節點,比如上面的to,和ten,中重復的單詞t只占用了一個節點。

模板

//節點
struct Node {//每個節點有26個子節點Node* son[26]{};//末尾標記,可用于區分前綴字符串和完整字符串bool end = false;
};
class Tire {Node* root = new Node();int find(string s) {Node* cur = root;for (char c : s) {int t = c - 'a';if (cur->son[t] == nullptr) {//沒找到返回0return 0;}cur = cur->son[t];}//找到完整的返回2,前綴字符串返回1return cur->end ? 2 : 1;}
public://插入字符串void insert(string word) {Node* cur=root;for(char c:word){c-='a';if(cur->son[c]==nullptr){cur->son[c]=new Node();}cur=cur->son[c];}cur->end=true;}//查詢完整字符串bool search(string word) {return find(word)==2;}//查詢前綴字符串bool startsWith(string prefix) {return find(prefix)!=0;}
};

例題

例題1

愛找事的小Z
題目描述:
小 Z 同學非常喜歡找事,現在有很多名為“事”的字符串,現在小 Z 想要找“事”,請你幫助他判斷,他今天是否找了兩件相同的事。
輸入描述
輸入第一行包含一個整數 n,表示小 Z 今天找了多少事。
接下來 n行分別表示 n 件事。
事的輸入量不超過 1e3,每個"事"字符串的長度不超過 1000,且所有字母均為小寫。
輸出描述
若有相同的事輸出1,否則輸出0。
輸入輸出樣例
示例1
輸入

12
acd
acd
asdfsdf
asd
f
saf
asdf
sfasdfs
f
asdf
asf
asdfs

輸出

1

示例2
輸入

21
adfasdfaasdf
asdfsfas
fa
sdfasd
fsd
fs
a
sda
fsd
afasd
f
sda
f
asdf
as
df
sda
gggggas
dfdsfe
def
a

輸出

1

示例
輸入

9
asdfasdfa
asdfb
asdc
fasd
fde
sadf
fg
hsadfasdfasdg
iggsadffsa

輸出

0
#include<bits/stdc++.h>
using namespace std;
//節點
struct Node {//每個節點有26個子節點Node* son[26]{};//末尾標記,可用于區分前綴字符串和完整字符串bool end = false;
};
class Tire {Node* root = new Node();int find(string s) {Node* cur = root;for (char c : s) {int t = c - 'a';if (cur->son[t] == nullptr) {//沒找到返回0return 0;}cur = cur->son[t];}//找到完整的返回2,前綴字符串返回1return cur->end ? 2 : 1;}
public://插入字符串void intsert(string s) {Node* cur = root;for (char c : s) {int t = c - 'a';if (cur->son[t] == nullptr) {cur->son[t] = new Node();}cur = cur->son[t];}cur->end = true;}//查詢字符串bool  check(string s) {return find(s) == 2;}
};
int main() {Tire tire;int n;cin >> n;int ans = 0;for (int i = 1; i <= n; i++) {string temp;cin >> temp;if (!tire.check(temp)) {tire.intsert(temp);}else {ans++;}}if (ans) {cout << 1;}else {cout << 0;}return 0;
}

例題2

小藍的神秘圖書館
問題描述
小藍是圖書館的管理員,他負責管理圖書館的所有書籍。圖書館有 N本書,每本書都有名字,分別為 S1,S2,…,SN。
圖書館的讀者們經常來詢問小藍,他們會給小藍一個字符串 T,希望小藍能告訴他們,圖書館里有多少本書的名字是以 T的前綴開頭的。小藍需要回答他們 M次這樣的詢問。
現在,小藍需要你的幫助。你能幫助小藍解決這個問題,從而提升圖書館的服務質量嗎?
輸入格式
第一行輸入兩個整數 N 和 M(1≤N,M≤1e4)。
接下來 N 行,每行輸入一個字符串 Si,表示圖書館中的一本書的名字。
接下來 M行,每行一個字符串 T,表示讀者的詢問。
輸入字符串的總長度不超過 2×1e5,且僅包含小寫字母。
輸出格式
對于每個詢問,輸出一個整數,表示圖書館中以字符串 T開頭的書的數量。
每個答案占一行。
樣例輸入

5 2
ababc
ababd
aba
ab
a
abab
ccc

樣例輸出

2
0
#include<bits/stdc++.h>
using namespace std;
struct Node {Node* son[26];int end = 0;
};
class Tire {Node* root = new Node();int dfs(Node* cur) {int res = 0;if (cur == nullptr) {return res;}if (cur->end) {res += cur->end;}for (int i = 0; i < 26; i++) {if (cur->son[i]) {res+=dfs(cur->son[i]);}}return res;}
public:void insert(string s) {Node* cur = root;for (char c : s) {c = c - 'a';if (cur->son[c] == nullptr) {cur->son[c] = new Node();}cur = cur->son[c];}cur->end++;}int find(string s) {Node* cur = root;for (char c : s) {c = c - 'a';if (cur->son[c] == nullptr) {return 0;}cur = cur->son[c];}return dfs(cur);}
};
int main() {Tire tire;int n, m;cin >> n >> m;for (int i = 1; i <= n; i++) {string s;cin >> s;tire.insert(s);}for (int i = 1; i <= m; i++) {string s;cin >> s;cout << tire.find(s) << '\n';}return 0;
}
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 2e5 + 10;
string str[N],s[N];
ll n = 0, m = 0;
ll trie[N][27], cnt[N];
ll idx = 2;
void insert(string a){ll p = 1;ll k = a.length() - 1;for (ll i = 1; i <= k; i++){if (!trie[p][a[i] - '0']) trie[p][a[i] - '0'] = idx++;p = trie[p][a[i] - '0'];cnt[p]++;}
}
ll query(string a){ll p = 1;ll k = a.length() - 1;ll ans = 0x3f3f3f;for (ll i = 1; i <= k; i++){p = trie[p][a[i] - '0'];ans = min(ans, cnt[p]);}return ans;
}
int main(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cin >> n >> m;for (ll i = 1; i <= n; i++){cin >> str[i];str[i] = '0' + str[i];insert(str[i]);}for (ll i = 1; i <= m; i++){cin >> s[i];s[i] = '0' + s[i];cout << query(s[i]) << endl;}return 0;
}

01Tire

理論

在這里插入圖片描述
x >> i & 1
(010)>>30 → (000)&(001) → 0
……
(010)>>2 → (000)&(001) → 0
(010)>>1 → (001)&(001) → 1
(010)>>0 → (010)&(001) → 0

1 << i
(001)<<2 → (100) → 4
(001)<<1 → (010) → 2
(001)<<0 → (001) → 1

res |= (1<< i)
(010)^(101) → (111) → 4+2+1=7
(011)^(101) → (110) → 4+2+0=6
(101)^(010) → (111) → 4+2+1=7
(111)^(010) → (101) → 4+0+1=5

模板

const int N = 1e5 + 10;
int son[32 * N][2], tot = 1;
//插入
void insert(int x)
{int o = 1;for (int i = 30; i >= 0; --i){int y = x >> i & 1;if (!son[o][y])son[o][y] = ++tot;o = son[o][y];}
}//查詢
int query(int x)
{int o = 1, res = 0;for (int i = 30; i >= 0; --i){int y = x >> i & 1;//找相反方向的,0找1,1找0,異或后為1,大小最大if (son[o][!y])o = son[o][!y], res |= (1ll << i);//如果該方向沒有,則按原有方向走elseo = son[o][y];}return res;
}

例題

XOR最大值
問題描述
給定一個整數數組 arr 和一個整數 q 表示查詢的數量。接下來的 q行,每行給出一個整數 x。對于每個 x,你需要找到 arr 中的一個數 y使得 xXORy的值最大,然后輸出這個最大值。
輸入格式
第一行包含一個整數 n,表示數組 arr 的大小。
第二行包含 n個整數,分別是 arr的元素。(0≤arr[i]≤1e9)。
第三行包含一個整數 q,表示查詢的數量。
接下來的 q行,每行包含一個整數 x。(0≤x≤1e9)。
輸出格式
對于每個查詢輸出一行,表示 xXORy 的最大值。
樣例輸入

5
3 5 7 10 12
3
3
7
10

樣例輸出

15
13
15
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int son[32 * N][2], tot = 1;void insert(int x)
{int o = 1;for (int i = 30; i >= 0; --i){int y = x >> i & 1;if (!son[o][y])son[o][y] = ++tot;o = son[o][y];}
}int query(int x)
{int o = 1, res = 0;for (int i = 30; i >= 0; --i){int y = x >> i & 1;if (son[o][!y])o = son[o][!y], res |= (1ll << i);elseo = son[o][y];}return res;
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n;cin >> n;for (int i = 1; i <= n; ++i){int x;cin >> x;insert(x);}int q;cin >> q;while (q--){int x;cin >> x;cout << query(x) << "\n";}
}
#include<bits/stdc++.h>
using namespace std;
struct Node {Node* son[2]{};
};
class Tire {Node* root = new Node();
public:void insert(int x) {Node* cur = root;for (int i = 30; i >= 0; i--) {int y = x >> i & 1;if (!cur->son[y]) {cur->son[y] = new Node();}cur = cur->son[y];}}int query(int x) {Node* cur = root;int res = 0;for (int i = 30; i >= 0; i--) {int y = x >> i & 1;if (cur->son[!y]) {res = res + (1 << i);cur = cur->son[!y];}else {cur = cur->son[y];}}return res;}
};
int main() {Tire tire;ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n;cin >> n;for (int i = 1; i <= n; ++i){int x;cin >> x;tire.insert(x);}int q;cin >> q;while (q--){int x;cin >> x;cout << tire.query(x) << "\n";}return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74829.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74829.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74829.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

厄瓜多爾主流收單方式:Pago Efectivo支付

PAGOEFECTIVO&#xff08;Pago Efectivo&#xff09;是秘魯主流的在線支付方式&#xff0c;由El Comercio Group開發&#xff0c;主要為用戶提供安全、便捷的在線支付解決方案&#xff0c;支持網銀和現金支付&#xff0c;適用于沒有信用卡或不愿透露銀行信息的消費者。 Pago Ef…

【文獻研究】含硼鋼中BN表面偏析對可鍍性的影響

《B 添加鋼的溶融 Zn めっき性に及ぼす BN 表面析出の影響》由JFE公司田原大輔等人撰寫。研究聚焦 B 添加鋼在低露點退火時 BN 形成對鍍鋅性的影響&#xff0c;對汽車用高強度鋼鍍鋅工藝優化意義重大。通過多組對比實驗&#xff0c;結合多種分析手段&#xff0c;明確了相關因素…

語法: ptr=malloc(size)

MALLOC( ) 語法: ptrmalloc(size) 參數: size是一個整數,表示被分配的字節個數; 返回值: 如果允許的話,返回值是一個指向被分配存儲器的指針;否則的話, 返回值是一個非指針; 功能: 該函數用來分配一定大小的空間給一個對象,其大小為size,但該空間的值為不確定值; 有…

JavaScript創建對象與構造函數

目錄 創建對象 一、創建對象的 5 種核心方式 1. 對象字面量&#xff08;直接量&#xff09; 2. 使用 Object.create() 3. 工廠模式 4. 構造函數模式 5. ES6 class 語法&#xff08;語法糖&#xff09; 二、構造函數與 new 關鍵字 1. 構造函數的作用 2. 構造函數的特征…

AIDD-人工智能藥物設計-深度學習助力提高兒童低級別膠質瘤復發風險預測的準確性

深度學習助力提高兒童低級別膠質瘤復發風險預測的準確性 兒童低級別膠質瘤&#xff08;pLGG&#xff09;是一種常見于兒童患者中的腦腫瘤&#xff0c;盡管大多數時候被認為是良性腫瘤&#xff0c;但是它們仍然可能導致相關癥狀和并發癥的發生&#xff0c;包括但不限于頭疼、癲…

redis的數據類型(1)

https://redis.io/docs/latest/develop/data-types/strings/ 社區版支持&#xff1a; String&#xff0c;字符串 Hash&#xff0c;key-value格式 List&#xff0c;根據插入順序排序 Set&#xff0c;集合 Sorted set&#xff0c;有排序 Stream&#xff0c; Bitmap&#xff0c; …

Nacos配置中心使用

Nacos配置中心 Nacos除了可以做注冊中心,&#x1f517;Nacos下載和注冊中心教程,同樣可以做配置管理來使用。 一、統一配置管理 當微服務部署的實例越來越多&#xff0c;達到數十、數百時&#xff0c;逐個修改微服務配置就顯得十分的不方便&#xff0c;而且很容易出錯。我們…

OpenCV輪廓檢測全面解析:從基礎到高級應用

一、概述 輪廓檢測是計算機視覺中的基礎技術&#xff0c;用于識別和提取圖像中物體的邊界。與邊緣檢測不同&#xff0c;輪廓檢測更關注將邊緣像素連接成有意義的整體&#xff0c;形成封閉的邊界。 輪廓檢測的核心價值 - 物體識別&#xff1a;通過輪廓可以識別圖像中的獨立物體…

Jenkins學習(B站教程)

文章目錄 1.持續集成CI2.持續交付CD3.持續部署4.持續集成的操作流程5.jenkins簡介6.后續安裝部署&#xff0c;見視頻 bilibili視頻 Jenkins是一個開源的、提供友好操作界面的持續集成(CI)工具&#xff0c;起源于Hudson&#xff08;Hudson是商用的&#xff09;&#xff0c;主要用…

ARM-UART

時鐘選擇PLCK,超時3ms自動發送&#xff0c;設置發送8位的緩沖區&#xff0c;且發送中斷 設置觸發深度&#xff0c;達到8字節將緩沖區數據發憷 中斷處理函數

Rust所有權詳解

文章目錄 Rust所有權所有權規則作用域 內存和分配移動與克隆棧空間堆空間 關于函數的所有權機制作為參數作為返回值 引用與租借垂懸引用 Rust所有權 C/C中我們對于堆內存通常需要自己手動管理&#xff0c;手動申請和釋放&#xff0c;即便有了智能指針&#xff0c;對于效率的影…

【在線OJ項目測試報告】

朋友們、伙計們&#xff0c;我們又見面了&#xff0c;本期來給大家帶來關于在線OJ項目的測試報告&#xff0c;如果看完之后對你有一定的啟發&#xff0c;那么請留下你的三連&#xff0c;祝大家心想事成&#xff01; C 語 言 專 欄&#xff1a;C語言&#xff1a;從入門到精通 數…

【HFP】藍牙HFP應用層核心技術研究

免提配置文件(Hands-Free Profile, HFP)作為實現設備間音頻通信的關鍵協議,廣泛應用于車載系統、藍牙耳機等場景。本文將基于最新技術規范,深入剖析HFP應用層的功能要求、協議映射及編解碼器支持,為藍牙開發工程師提供詳盡的技術指南。 一、HFP應用層功能全景圖 HFP定義…

橫掃SQL面試——PV、UV問題

&#x1f4ca; 橫掃SQL面試&#xff1a;UV/PV問題 &#x1f31f; 什么是UV/PV&#xff1f; 在數據領域&#xff0c;UV&#xff08;Unique Visitor&#xff0c;獨立訪客&#xff09; 和 PV&#xff08;Page View&#xff0c;頁面訪問量&#xff09; 是最基礎也最重要的指標&…

【C++】第八節—string類(上)——詳解+代碼示例

hello&#xff0c;又見面了&#xff01; 云邊有個稻草人-CSDN博客 C_云邊有個稻草人的博客-CSDN博客——C專欄&#xff08;質量分高達97&#xff01;&#xff09; 菜鳥進化中。。。 目錄 一、為什么要學習string類&#xff1f; 1.1 C語言中的字符串 1.2 面試題(暫不做講解) …

如何判斷JVM中類和其他類是不是同一個類

如何判斷JVM中的類是否為同一個類 在Java虛擬機(JVM)中&#xff0c;判斷兩個類是否相同需要同時滿足以下三個條件&#xff1a; 1. 類全限定名必須相同 包括包名類名的完整路徑必須完全一致例如&#xff1a;java.lang.String和com.example.String被視為不同類 2. 加載該類的…

ifconfig 使用詳解

目錄 一、基本語法二、常見用途及示例1. 查看所有網絡接口信息2. 啟用/禁用網絡接口3. 配置 IP 地址和子網掩碼4. 修改 MAC 地址5. 啟用混雜模式&#xff08;Promiscuous Mode&#xff09;6. 設置 MTU&#xff08;最大傳輸單元&#xff09; 三、其他選項四、常見問題1. 新系統中…

1. 標準庫的強依賴(核心原因)

1. 標準庫的強依賴&#xff08;核心原因&#xff09; 容器操作&#xff08;如 std::vector 擴容&#xff09; 當標準庫容器&#xff08;如 std::vector&#xff09;需要重新分配內存時&#xff0c;它會嘗試移動現有元素到新內存&#xff0c;而非拷貝&#xff08;為了性能&…

【MySQL】常用SQL--持續更新ing

一、配置信息類 1.查看版本 select version; 或 select version(); 2.查看配置 show global variables where variable_name in (basedir,binlog_format,datadir,expire_logs_days,innodb_buffer_pool_size,innodb_log_buffer_size,innodb_log_file_size,innodb_log_files_i…

Day82 | 靈神 | 快慢指針 重排鏈表

Day82 | 靈神 | 快慢指針 重排鏈表 143.重排鏈表 143. 重排鏈表 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 筆者直接給跪了&#xff0c;這個難度真是mid嗎 直接去看靈神的視頻 環形鏈表II【基礎算法精講 07】_嗶哩嗶哩_bilibili 1.簡單來說就是&#xf…