字典樹(Trie樹)模板 陣列表示 + 連結串列表示
阿新 • • 發佈:2018-12-11
陣列模擬,缺點是並不知道要開多大,可能會出現陣列開小導致wrong answer。
對應題目:hdu 1251
#include <iostream> #include <cstdio> #include <cstring> #define fuck cout << "wtf???\n" using namespace std; typedef long long ll; const int maxn = 1e6 + 100; int num; struct Tries { int child[27]; int cnt; void Init(){ cnt = 0; memset(child, -1, sizeof(child)); } }Trie[maxn]; void Insert(string st) { int tmp = 0; for(int i = 0; i < (int)st.size(); ++ i) { int r = st[i] - 'a'; if(Trie[tmp].child[r] == -1) { Trie[tmp].child[r] = ++num; Trie[num].Init(); } tmp = Trie[tmp].child[r]; Trie[tmp].cnt++; } } int Query(string st) { int tmp = 0; for(int i = 0; i < (int)st.size(); ++ i) { int r = st[i] - 'a'; if(Trie[tmp].child[r] == -1) { return 0; } tmp = Trie[tmp].child[r]; } return Trie[tmp].cnt; } void init() { num = 0; Trie[0].cnt = 0; memset(Trie[0].child, -1, sizeof(Trie[0].child)); } string st; bool read() { char ch; st.clear(); int cnt = 0; while(ch = getchar()) { if(ch == '\n') break; //cout << ch << endl; cnt++; st += ch; } if(cnt == 0) return false; else return true; } int main() { //freopen("in.txt", "r", stdin); init(); while(read()) { Insert(st); } while(cin >> st) { cout << Query(st) << endl; } return 0; }
連結串列表示:不用擔心空間的問題了,但是反覆申請空間還是比較費時間的,而且訪問速度肯定是比不上陣列。
對應題目:hdu 1075
#include <iostream> #include <cstdio> #include <cstring> #define fuck cout << "wtf???\n" using namespace std; char st[3030], str[3030]; struct node { node *child[26]; char ss[15]; bool flag; void Init(){ for(int i = 0; i < 26; ++ i) child[i] = NULL; flag = false; } }*Trie; void Insert(char *st, char *str) { int len = strlen(st); node *tmp = Trie; for(int i = 0; i < len; ++ i) { int r = st[i] - 'a'; if(tmp->child[r] == NULL) { tmp->child[r] = new node; tmp->child[r]->Init(); } tmp = tmp->child[r]; } strcpy(tmp->ss, str); tmp->flag = true; } void Search(int l, int r) { node *tmp = Trie; for(int i = l; i < r; ++ i) { int x = str[i] - 'a'; if(tmp->child[x] == NULL) { for(int j = l; j < r; ++ j) printf("%c", str[j]); return ; } tmp = tmp->child[x]; } if(tmp->flag) printf("%s", tmp->ss); else { for(int j = l; j < r; ++ j) printf("%c", str[j]); } } bool read() //害怕超時就自己寫了個讀入函式 { char ch; int i = 0; while(ch = getchar()) { if(ch == '\n') break; str[i++] = ch; } str[i] = '\0'; if(strcmp(str, "END") == 0) return false; return true; } int main() { //freopen("in.txt", "r", stdin); Trie = new node; Trie->Init(); scanf("%s", st); while(scanf("%s", st)) { if(strcmp(st, "END") == 0) break; scanf("%s", str); Insert(str, st); } scanf("%s", st); getchar(); while(1) { if(!read()) break; int pos = 0; int i = 0; int len = strlen(str); while(i < len) { while((str[i] < 'a' || str[i] > 'z') && i < len) { printf("%c", str[i]); i++; } pos = i; while((str[i] >= 'a' && str[i] <= 'z') && i < len) ++ i; if(pos >= len || i > len) continue; Search(pos, i); } printf("\n"); } return 0; }