给你很多单词(Only lowercase No repeated words),要你统计以某字符串为前缀的单词数量(包括本身)。
思路
只需在建树时,维护一个sum[id],即对每个单词中所出现的前缀+1。
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn = 400005;
int trie[maxn][26],len,root,tot,sum[maxn];
bool p;
char s[11];
void insert(){
len = strlen(s);
root = 0;
for(int i=0;i<len;i++){
int id = s[i]-'a';
if(trie[root][id]==0) trie[root][id] = ++tot;
sum[trie[root][id]]++;
root = trie[root][id];
}
}
int search(){
root = 0;
len = strlen(s);
for(int i=0;i<len;i++){
int id = s[i]-'a';
if(trie[root][id]==0) return 0;
root = trie[root][id];
}
return sum[root];
}
int main(){
while(gets(s)){
if(strlen(s)==0) break;
insert();
}
while(cin>>s){
cout<<search()<<endl;
}
return 0;
}
还有一道类似的题目
求字典中是否有某前缀的单词。
只需将上题的sum数组改为维护一个vis数组,即某前缀是否出现过即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 400005;
int trie[maxn][26],len,root,tot,vis[maxn];
bool p;
char s[11];
void insert(){
len = strlen(s);
root = 0;
for(int i=0;i<len;i++){
int id = s[i]-'a';
if(trie[root][id]==0) trie[root][id] = ++tot;
vis[trie[root][id]]=1;
root = trie[root][id];
}
}
int search(){
root = 0;
len = strlen(s);
for(int i=0;i<len;i++){
int id = s[i]-'a';
if(trie[root][id]==0) return 0;
root = trie[root][id];
}
return vis[root];
}
int main(){
int n,m;
scanf("%d",&n);
while(n--){
scanf("%s",s);
insert();
}
scanf("%d",&m);
while(m--){
scanf("%s",s);
printf("%s\n",search()==1?"YES":"NO");
}
return 0;
}