一、Trie树的用途
- 前缀匹配
前缀匹配常用于搜索提示,比如使用知乎搜索时,如果输入的字符串没有匹配的结果,会返回与输入结果相同前缀最相似的结果。这一点(Trie)树确实牛,其它的数据结构和它没法比,但下面两个就不是典型应用了:
-
词频统计
-
大量字符串排序
-
字符串是否存在与集合中
这三种情况下,对比(unordered\_map<string, int>)这样的(hash)方式,没有什么优势~
二、什么是Trie树
上栗子:
三、Trie树解法
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int son[N][26];
int idx;
int cnt[N];
// 插入
void insert(string str) {
int p = 0;
for (int i = 0; i < str.size(); i++) {
int u = str[i] - 'a';
//逢山开道,遇水搭桥
if (!son[p][u]) son[p][u] = ++idx;
//走进去
p = son[p][u];
}
//记录以此终点的个数+1
cnt[p]++;
}
//查询
int query(string str) {
int p = 0;
for (int i = 0; i < str.size(); i++) {
int u = str[i] - 'a';
if (!son[p][u]) return 0;//中间找不到结点就停止
p = son[p][u];//继续深入查找~
}
//以p为结尾的单词的个数
return cnt[p];
}
int main() {
//优化输入
ios::sync_with_stdio(false);
int n;
cin >> n;
while (n--) {
char op;
//输入的字符串
string str;
cin >> op >> str;
//插入到Trie树
if (op == 'I') insert(str);
//表示x在集合中出现的次数
else printf("%d
", query(str));
}
return 0;
}
四、STL解法
#include <bits/stdc++.h>
using namespace std;
int n;
char ch;
string s;
unordered_map<string, int> _map;
int main() {
//优化输入
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> ch;
cin >> s;//虽然unordered_map本质原理与数组不同,但其实可以当数组用滴
if (ch == 'I') _map[s]++;
else cout << _map[s] << endl;
}
return 0;
}