【数据结构-树论】字典树(Trie)

引入

观看例题,可以看出暴力解,时间复杂度大概为 \(O(Tnq)\),最差情况 \(1e15\),我觉得洛谷测评姬没有那么快。

单词哦,查字典,怎么查:

先找第一个字母,再找第二个字母 \(\dots \dots\)

于是乎发明字典树(话说我本来是想用二分做的。)

定义及思想

一种树形结构,基于字符串前缀来进行查找,减少比较,以空间换时间。

作用及实现

多数用于字符串的查找以及排序。

是一个 \(26\) 叉树。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
const int man = 5e5+10;
class Graph {
public:
    int len, hed[man];
    int ver[man], nxt[man];
    void Ins (int u, int v) {
        ver[++len] = v;
        nxt[len] = hed[u];
        hed[u] = len;
        return ;
    }
    void DIns (int u, int v) {
        Ins(u, v), Ins(v, u);
        return ;
    }
} ;

/*
Windows:
g++ test.cpp -o test.exe
get-content .\test.in | .\test.exe > test.out
*/

int n, q, idx;
int cnt[man], flag[man];
int tr[man][30];
void make (string) ;
string check (string) ;
int main () {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    for(int i = 0; i <= idx; ++ i) {
        cnt[i] = 0;
        for(int j = 0; j < 26; ++ j) tr[i][j] = 0;
    } idx = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++ i) {
        string s;
        cin >> s;
        make(s);
    } scanf("%d", &q);
    for (int i = 1; i <= q; ++ i) {
        string s;
        cin >> s;
        cout << check(s);
    }
    return 0;
}

// ---

void make (string str) {
    int p = 0;
    for (int i = 0; i < str.length(); ++ i) {
        int j = str[i]-'a';
        if (!tr[p][j]) tr[p][j] = ++ idx;
        p = tr[p][j];
    } ++ cnt[p];
    return ;
}

string check (string str) {
    int res = 0, p = 0, j;
    for (int i = 0; i < str.length(); ++ i) {
        j = str[i]-'a';
        if (!tr[p][j]) return "WRONG\n";
        p = tr[p][j];
    } return cnt[p]? flag[p]++? "REPEAT\n" : "OK\n" : "WRONG\n";
}

扩展

posted @ 2023-08-20 09:07  STA_Morlin  阅读(53)  评论(0)    收藏  举报