一、模板
结构体
struct Trie{
int val;
Trie *nex[26];
Trie(){
val = 0;
for(int i = 0; i < 26; ++i) nex[i] = NULL;
}
};
建树
void build(string x, Trie *root){
int len = x.size();
for(int i = 0; i < len; ++i){
int cur = x[i] - 'a';
if(root -> nex[cur] == NULL){
root -> nex[cur] = new Trie();
}
root = root -> nex[cur];
++root -> val;
}
}
查询
int query(string x, Trie *root){ int len = x.size(); for(int i = 0; i < len; ++i){ int cur = x[i] - 'a'; if(root -> nex[cur] == NULL) return 0; root = root -> nex[cur]; } return root -> val; //val存的是包含某前缀的字符串数 }
二、简单例题
(1)HDU 1251
题意:统计以某个字符串为前缀的单词数量(单词本身也是自己的前缀)。单词只有小写字母组成,不会有重复的单词出现。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<sstream>
typedef long long LL;
const int INF = 0x3f3f3f3f;
using namespace std;
const int MAXN = 100000 + 10;
const double eps = 1e-8;
int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a < b ? -1 : 1;
}
struct Trie{
int val;
Trie *nex[26];
Trie(){
val = 0;
for(int i = 0; i < 26; ++i) nex[i] = NULL;
}
};
char s[20];
void build(Trie *root){
int len = strlen(s);
for(int i = 0; i < len; ++i){
int cur = s[i] - 'a';
if(root -> nex[cur] == NULL){
root -> nex[cur] = new Trie();
}
root = root -> nex[cur];
++root -> val;
}
}
int query(Trie *root){
int len = strlen(s);
for(int i = 0; i < len; ++i){
int cur = s[i] - 'a';
if(root -> nex[cur] == NULL) return 0;
root = root -> nex[cur];
}
return root -> val;
}
int main(){
Trie *root = new Trie();
while(gets(s) && s[0] != ' '){
build(root);
}
while(scanf("%s", s) == 1){
printf("%d
", query(root));
}
return 0;
}
(2)KickStart A轮 D题:https://www.cnblogs.com/tyty-Somnuspoppy/p/12546794.html
题意:有N个字符串,每个字符串只包含字母A~Z,要求把字符串按K个一组进行分组,每个字符串只能分到一个组中。分好后,每个组的score为该组所有字符串的最长公共前缀。问分组后每个组的score之和的最大值。
(3)HDU 2072
题意:统计一篇文章里不同单词的总数。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<sstream>
typedef long long LL;
const int INF = 0x3f3f3f3f;
using namespace std;
const int MAXN = 1000000 + 10;
const double eps = 1e-8;
int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a < b ? -1 : 1;
}
struct Trie{
int val;
Trie *nex[26];
Trie(){
val = 0;
for(int i = 0; i < 26; ++i) nex[i] = NULL;
}
};
int ans;
void build(string x, Trie *root){
int len = x.size();
for(int i = 0; i < len; ++i){
int cur = x[i] - 'a';
if(root -> nex[cur] == NULL){
root -> nex[cur] = new Trie();
}
root = root -> nex[cur];
}
if(root -> val == 0){
++ans;
root -> val = 1;
}
}
string s;
int main(){
while(getline(cin, s) && s != "#"){
Trie *root = new Trie();
stringstream ss(s);
string x;
ans = 0;
while(ss >> x){
build(x, root);
}
printf("%d
", ans);
}
return 0;
}