字典树(Trie)
字典树(Trie)的基本概念
字典树是一种树形数据结构,用于高效存储和检索字符串集合。其核心特点是利用字符串的公共前缀减少查询时间,适合处理前缀匹配、词频统计等问题。
字典树的C++实现(模板)
struct treename {int nex[500005][26];int cnt = 0;int exist[500005]; // 该结点结尾的字符串是否存在void initialize() {//初始化结构体memset(nex, 0, sizeof(nex));memset(exist, 0, sizeof(exist));cnt == 0;}void insert(string s) {// 插入字符串int len = s.size();int p = 0;for (int i = 0; i < len; i++) {int j = s[i] - 'a';if (!nex[p][j]) nex[p][j] = ++cnt;p = nex[p][j];}exist[p] = 1;}bool find(string s) {//查找字符串(是否存在以某一样的字符串)int len = s.size();int p = 0;for (int i = 0; i < len; i++) {int j = s[i] - 'a';if (!nex[p][j]) return false;p = nex[p][j];}if(exist[p]!=0) {return true;}else {return false;}}
}tree;
应用场景
- 自动补全:根据前缀快速匹配候选词。
- 拼写检查:快速判断单词是否存在。
- IP路由:最长前缀匹配。
复杂度分析
- 时间:插入和查询均为O(L),L为字符串长度。
P2580 于是他错误的点名开始了 - 洛谷
思路:
将exist在每次查询后,如果存在就++,然后判断其值。
#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
using namespace std;
struct treename {int nex[500005][26];int cnt = 0;int exist[500005]; // 该结点结尾的字符串是否存在void initialize() {//初始化结构体memset(nex, 0, sizeof(nex));memset(exist, 0, sizeof(exist));cnt == 0;}void insert(string s) {// 插入字符串int len = s.size();int p = 0;for (int i = 0; i < len; i++) {int j = s[i] - 'a';if (!nex[p][j]) nex[p][j] = ++cnt;p = nex[p][j];}exist[p] = 1;}int find(string s) {//查找字符串(是否存在以某一样的字符串)int len = s.size();int p = 0;for (int i = 0; i < len; i++) {int j = s[i] - 'a';if (!nex[p][j]) return -1;p = nex[p][j];}if(exist[p]!=0) {exist[p]++;return p;}else {return -1;}}
}tree;
int n, m;void solve() {tree.initialize();cin >> n;string s;for (int i = 0; i < n; i++) {cin >> s;tree.insert(s);}cin >> m;for (int i = 0; i < m; i++) {cin >> s;int r = tree.find(s);if (r == -1) {cout << "WRONG" << endl;}else if (tree.exist[r] == 2) {cout << "OK" << endl;}else {cout << "REPEAT" << endl;}}return;
}
int main(){ios::sync_with_stdio(false); // 禁用同步std::cin.tie(nullptr),std::cout.tie(nullptr); // 解除cin与cout绑定int t = 1;//cin >> t;while (t--) {solve();}return 0;
}