Trie树(也叫前缀树)
其实我不知道要去写什么。。。特点:典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 以上都是我想告诉大家的!!!
// ch[i][j] 表示的就是第i个结点编号为j的子结点
const int maxnode = 2e6+5 , sigma_size = 28;
struct node{
int ch[maxnode][sigma_size];
int val[maxnode];
int sum[maxnode]; // 出现的次数
int tot; // 结点个数
void init() { tot = 1; memset(ch[0],0,sizeof(ch[0])); memset(sum,0,sizeof(sum)); }
int idx(char c) { return c - 'a'; }
void insert(char *s, int v){
int u = 0, n =strlen(s);
for(int i = 0; i < n; i++){
int id = idx(s[i]);
if(!ch[u][id]){ // 结点不存在
memset(ch[tot],0,sizeof(ch[tot]));
val[tot] = 0;
ch[u][id] = tot++; // 新的结点
}
sum[ch[u][id]]++;
u = ch[u][id];
}
val[u] = v;
}
int query(char *s, int pos){
int n = strlen(s), u = 0;
for(int i = 0; i < n; i++){
int id = idx(s[i]);
if(!ch[u][id]) return 0;
u = ch[u][id];
}
return sum[u];
}
}T;
字典树第一题
题目传送门Hdu1251
题意:统计以某个串为前缀的单词个数!
我的理解:好像就是裸的Trie! 增加一个sum数组,sum[i]表示的就是i结点的子结点的个数! 然后跑一边这个Trie树!
AC代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define swap(a,b) (a=a+b,b=a-b,a=a-b)
//#define memset(a,v) memset(a,v,sizeof(a))
#define X (sqrt(5)+1)/2.0 //Wythoff
#define Pi acos(-1)
#define e 2.718281828459045
#define eps 1.0e-8
#define N 300010
using namespace std;
typedef long long int ll;
const int maxnode = 2e6+5 , sigma_size = 28;
struct node{
int ch[maxnode][sigma_size];
int val[maxnode];
int sum[maxnode]; // 出现的次数
int tot; // 结点个数
void init() { tot = 1; memset(ch[0],0,sizeof(ch[0])); memset(sum,0,sizeof(sum)); }
int idx(char c) { return c - 'a'; }
// 插入字符串s,附加的信息是v,注意v必须为非0,0表示的就是‘本节点不是单词结点’
void insert(char *s, int v){
int u = 0, n =strlen(s);
for(int i = 0; i < n; i++){
int id = idx(s[i]);
if(!ch[u][id]){ // 结点不存在
memset(ch[tot],0,sizeof(ch[tot]));
val[tot] = 0;
ch[u][id] = tot++; // 新的结点
}
sum[ch[u][id]]++;
u = ch[u][id];
}
val[u] = v;
}
int query(char *s, int pos){
int n = strlen(s), u = 0;
for(int i = 0; i < n; i++){
int id = idx(s[i]);
if(!ch[u][id]) return 0;
u = ch[u][id];
}
return sum[u];
}
}T;
int main(){
T.init();
char a[2000005];
while(gets(a)){
if(a[0] == '\0') break;
T.insert(a,1);
}
while(scanf("%s",a)!=EOF){
printf("%d\n",T.query(a,1000));
}
return 0;
}
字典树第二题
题目传送门Hdu1251
题意:统计以某个串为前缀的单词个数!
我的理解:好像就是裸的Trie! 增加一个sum数组,sum[i]表示的就是i结点的子结点的个数! 然后跑一边这个Trie树!