字典树
树状结构保存字符串,查找快,判断前缀快。
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
例题: link.
代码(指针)
#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
// #include <unordered_set>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define pb push_back
#define T int T;scanf("%d",&T);while(T--)
const ll mod=1e6+3;
const int maxn = 1e5+5;
struct Trie{
int num; //到这个节点为前缀的单词个数
Trie *nxt[30]; //指向26个字母
};
Trie *root; //根结点不放字母
void init(Trie *p){
for(int i = 0; i < 30; i++)
p->nxt[i]=NULL;
p->num = 0;
}
void insert(string s){
Trie *cnt = root; //从根结点开始遍历
int len = s.size();
for(int i = 0; i < len; i++){
int id = s[i]-'a';
if(cnt->nxt[id]==NULL){ //如果当前节点下面没有第i个字母,就添加新节点;
Trie *p = new Trie();
// init(p);
cnt->nxt[id] = p;
}
cnt = cnt->nxt[id]; //更新节点位置
cnt->num++; //前缀+1
}
}
int find(string s){
Trie *cnt = root; //从根节点开始找
int len = s.size();
int ans = 0;
for(int i = 0; i < len; i++){
int id = s[i]-'a';
if(cnt->nxt[id]==NULL) return 0; //如果找不到,以s为前缀的单纯数为0
cnt = cnt->nxt[id];
ans = cnt->num; //更新值
}
return ans;
}
int main(){
root = new Trie();
// cout << root->nxt[1] << endl;
// init(root);
string s;
while(getline(cin,s)){ //输入单词
if(s=="") break;
insert(s);
}
while(cin >> s){
int ans = find(s); //统计以s为前缀的单词数量
cout << ans << endl;
}
return 0;
}
/*
7
bababa
band
bee
absolute
absord
acm
beer
*/
代码(数组)
#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include<sstream>
// #include <unordered_set>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define pb push_back
#define T int T;scanf("%d",&T);while(T--)
const ll mod=1e9+7;
const int maxn = 2e6+5;
int trie[maxn][30];
int sum[maxn];
int cnt;
int n,k;
void insert(string s){
int root=0;
for(int i = 0; i < s.size(); i++){
int id=s[i]-'a';
if(trie[root][id]==0){
trie[root][id]=++cnt;
}
sum[trie[root][id]]++;
root=trie[root][id];
}
// vis[root]=1;
}
int find(string s){
int ans = 0;
int root=0;
for(int i = 0; i < s.size(); i++){
int id=s[i]-'a';
if(trie[root][id]==0) return 0;
ans = sum[trie[root][id]];
root = trie[root][id];
}
return ans;
// return !vis[root];
}
int main(){
string s;
while(getline(cin,s)){ //输入单词
if(s=="") break;
insert(s);
}
while(cin >> s){
int ans = find(s); //统计以s为前缀的单词数量
cout << ans << endl;
}
return 0;
}
/*
5 6 2
1 1 2 5 2
5 6 2
1 1 1 5 2
*/