Trie字典樹模板及栗子
模板
Trie字典樹大致可以分為兩種實現方式,一種是陣列,另一種是指標,那麼我們就整理了兩個模板:
陣列的實現:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <cmath> #include <map> using namespace std; const int N = 1000000; int ch[N][26],val[N],tot; //陣列實現的話,總是拿不準ch陣列的大小,我們不確定生成的節點會有多少 void Init() { memset(ch[0],0,sizeof(ch[0])); tot = 1; memset(val,0,sizeof(val)); } void Insert(char *s,int x) { int u = 0,len = strlen(s); for(int i =0 ;i < len;i ++) { int v = s[i]-'a'; if(!ch[u][v]) { memset(ch[tot],0,sizeof(ch[tot])); val[tot] = 0; ch[u][v] = tot ++; } u = ch[u][v]; } val[u] = x;//結尾位置設定為權重,其餘位置都設定為0 } int Find(char *s) { int u = 0,len = strlen(s); for(int i =0;i < len;i ++) { int v = s[i]-'a'; if(!ch[u][v]) return 0; u = ch[u][v]; } return val[u]; } void Del(char *s) { int u = 0,len = strlen(s); for(int i =0 ;i < len;i ++) { int v = s[i] - 'a'; if(!ch[u][v]) return ; u = ch[u][v]; } val[u] = 0;//刪除時就是將最後一個位置的權值設定為0 }
指標實現
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <cmath> #include <map> using namespace std; //指標實現較為方便,並且也很容易理解 struct Trie { Trie *next[26]; int val; }; Trie *root; void Init() { root = (Trie *)malloc(sizeof(Trie)); for(int i = 0;i < 26;i ++) root->next[i] = NULL; root->val = 0; } void Insert(char *s) { Trie *p = root,*q; int len = strlen(s); for(int i = 0;i < len;i ++) { int v = s[i] - 'a'; if(p->next[v] == NULL) { q = (Trie *)malloc(sizeof(Trie)); q->val = 0; for(int j = 0;j < 26;j ++) q->next[j] = NULL; p->next[v] = q; } p = p->next[v]; } p->val = 1; } int Find(char *s) { int len = strlen(s); Trie *p = root; for(int i =0 ;i < len;i ++) { int v = s[i] - 'a'; p = p->next[v]; if(p == NULL) return -1; } return p->val; } void Del(Trie *s) { if(s == NULL) return ; for(int i =0;i < 26;i ++) if(s->next[i]) Del(s->next[i]); delete s; }
栗子
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N = 1000000; int sz; int ch[N][26]; int val[N]; struct Trie { Trie(){ sz = 1;//這裡要把0節點空出來,作為全部的根節點 memset(ch[0],0,sizeof(ch[0])); memset(val,0,sizeof(val)); } int idx(char c) { return c-'a'; } void Insert(char *s,int v) { int u = 0,len = strlen(s); for(int i =0 ;i < len;i ++) { int c = idx(s[i]); if(!ch[u][c])//表示這個節點重新作為一個新的節點,下面仍然還有26個子節點 { memset(ch[sz],0,sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; val[u] ++; } } int Read(char *s) { int u = 0,len = strlen(s); for(int i = 0;i < len;i ++) { int c = idx(s[i]); if(!ch[u][c]) return -1; else u = ch[u][c]; } if(val[u] == 0) return 1; else return 2; } int Get_num(char *s) { int u = 0,len = strlen(s); for(int i = 0;i < len;i ++) { int c = idx(s[i]); if(!ch[u][c]) return 0; else u = ch[u][c]; } return val[u]; } }; int main() { Trie T; char s[15]; while(1) { gets(s); if(s[0] == '\0') break; T.Insert(s,1); } while(gets(s)) { printf("%d\n",T.Get_num(s)); } return 0; }
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
struct Trie
{
Trie *next[26];
char *val;
};
Trie *root;
void Init()
{
root = (Trie *)malloc(sizeof(Trie));
for(int i = 0;i < 26;i ++)
root->next[i] = NULL;
root->val = NULL;
}
void Insert(char *s,char *str)
{
Trie *p = root,*q;
int len = strlen(s);
for(int i = 0;i < len;i ++)
{
int v = s[i] - 'a';
if(p->next[v] == NULL)
{
q = (Trie *)malloc(sizeof(Trie));
q->val = NULL;
for(int j = 0;j < 26;j ++)
q->next[j] = NULL;
p->next[v] = q;
}
p = p->next[v];
}
p->val = new char[11];
strcpy(p->val,str);
}
void Find(char *s)
{
int len = strlen(s);
Trie *p = root;
for(int i =0 ;i < len;i ++)
{
int v = s[i] - 'a';
p = p->next[v];
if(p == NULL) {printf("%s",s);return ;}
}
if(p->val) printf("%s",p->val);
else printf("%s",s);
}
void Del(Trie *s)
{
if(s == NULL)
return ;
for(int i =0 ;i < 26;i ++)
{
if(s->next[i])
Del(s->next[i]);
}
delete s->val;
delete s;
}
int main()
{
char s[15],s1[15];
Init();
scanf("%s",s);
while(scanf("%s %s\n",s,s1) && strcmp(s,"END"))
{
Insert(s1,s);
}
char str[3100],part[100];
while(gets(str) && strcmp(str,"END"))
{
int index = 0;
int len = strlen(str);
for(int i = 0;i < len;i ++)
{
if(islower(str[i]))
part[index++] = str[i];
else
{
part[index] = '\0';
Find(part);
index = 0;
printf("%c",str[i]);
}
}
puts("");
}
}
參考部落格
相關推薦
Trie字典樹模板及栗子
模板Trie字典樹大致可以分為兩種實現方式,一種是陣列,另一種是指標,那麼我們就整理了兩個模板:陣列的實現:#include <iostream> #include <cstdio> #include <string> #include &
字典樹模板及例題
(一)Trie的簡介 Trie樹,又稱字典樹,單詞查詢樹或者字首樹,是一種用於快速檢索的多叉樹結構,如英文字母的字典樹是一個26叉樹,數字的字典樹是一個10叉樹。他的核心思想是空間換時間,空間消耗大但是插入和查詢有著很優秀的時間複雜度。 (二)Trie的定義 Trie
字典樹模板
nbsp spa else space iostream ins out ring eat #include<iostream> #include<string> using namespace std; //表示next數組的長度,表示26個
Trie 字典樹
src spa main ets strcmp() ems next arc ear 1、UVa 1401 Remember the Word 題意:給出n個字符串集合,問其有多少種組合方式形成目標字符串。 思路:對n個字符串集合建立Trie樹,保存每個結點的字
bzoj3261: 最大異或和 可持久化字典樹模板
roo CP 前綴和 sum oot 可持久化 可持久化字典樹 == tdi 可持久化字典樹不過記得是兩次前綴和,所以記得減2,還有p=1的情況。 #include<bits/stdc++.h> using namespace std; int l[18000
CH 1601 - 字首統計 - [字典樹模板題]
題目連結:傳送門 描述給定 $N$ 個字串 $S_1,S_2,\cdots,S_N$,接下來進行 $M$ 次詢問,每次詢問給定一個字串 $T$,求 $S_1 \sim S_N$ 中有多少個字串是 $T$ 的字首。輸入字串的總長度不超過 $10^6$,僅包含小寫字母。 輸入格式第一行兩個整數 $N,M$。接
字典樹模板題 Shortest Prefixes
B - Shortest Prefixes Time Limit:1000MS Memory Limit:30000KB Description A prefix of a string is
字典樹模板題(統計難題 HDU - 1251)
https://vjudge.net/problem/HDU-1251 標準的字典樹模板題: 也注意一下輸入方法: #include<iostream> #include<cstdio> #include<cstring> using namespace std
字典樹模板(有待更新,連結串列版)
連結串列版:空間小,時間大。 陣列版:空間大,時間小 struct node { int num; node *next[maxn]; }; //字典樹 class Tree{ public: node *head; //建構函式 Tree() {
poj--3630 Phone List(Trie字典樹)
3630-Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 34575 Accepted: 9924 Description Given a l
hdu1251(字典樹模板)
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=2000000+10; c
HDU1251字典樹模板
Problem Description Ignatius最近遇到一個難題,老師交給他很多單詞(只有小寫字母組成,不會有重複的單詞出現),現在老師要他統計出以某個字串為字首的單詞數量(單詞本身也是自己的字首). Input 輸入資料的第一部分是一張
Trie字典樹
本來刷dp刷得好好的…突然要講…那就學學吧 以下為兩種寫法 桶儲存 : 空間換取時間 深度作為字串長度,每個元素作為一個長度為26的桶,每個的下標代表相應字母的序號,存下一個元素的id 具體實現虛擬碼
1671 Phone List (字典樹模板)
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone cat
資料結構——Trie 字典樹 字首樹
一、什麼是Trie Trie不同於二分搜尋樹、堆、線段樹等二叉樹結構,Trie是一個多叉樹。使用場景:通訊錄高效搜尋,專為處理字串設計的。 比如字典中有n條資料,如果使用樹結構,查詢的時間複雜度是O(logn),如果有100萬條資料的話,logn大約是20,如果有1億
字典樹模板題 Shortest Prefixes
B - Shortest Prefixes Time Limit:1000MS Memory Limit:30000KB Description A prefix of a string is a substring starting at the be
字典樹模板(陣列實現和指標實現)
///這裡以輸入字串後,查詢字串出現的次數為例#include<bits/stdc++.h>#define MAX 26using namespace std;typedef struct TrieNode ///Trie節點宣告{ int num;
HDU 4825 Xor Sum 01字典樹模板
題目連結 思路 01字典樹模板題,將所有數從高位開始插入到樹中。 #include<cstdio> #include<iostream> #include<a
poj 3630 / hdu 1671 Phone List 【Trie字典樹 動態建立&靜態建立】
Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 25160 Accepted: 7641 Description Given a list of phone numb
HDU4825 01字典樹模板題
題解: 第一次知道字典樹還能這樣用,果然還是做題太少了。。ORZ,感覺很多異或的題都可以用字典樹去解決#include<stdio.h> #include<string.h> #include<algorithm> using nam