字典树,就是树形的字母排列,从根节点开始(根节点不代表任何字母),它的每一个子节点都有一个不同的字母,这样,从根节点开始沿任何路径到达一个叶子节点,路过的字母组合就是一个字符串,字典树在字符串的存储和查找上有很大的优越性,下面是用字典树写的两个题。
hdu 1251
/*
这道题就是标准的字典树,存储给出的所有的在字典中给出的字符串和其前缀,统计其数目,存储在字典树中,然后就可以在O(len(m))的时间内查询给出的模式串的答案了
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Trie{
int v;
struct Trie *next[26];
} root;
void creat(char *str)
{
int len = strlen(str);
struct Trie *p = &root,*q;
for (int i = 0; i< len; i++){
int id = str[i] - 'a';
if (p->next[id] == NULL){
q = (Trie *)malloc(sizeof(root));
q->v = 1;
for (int j = 0; j< 26; j++)
q->next[j] = NULL;
p->next[id] = q;
p = p->next[id];
}
else {
p->next[id]->v++;
p = p->next[id];
}
}
}
int search(char *str)
{
int len = strlen(str);
struct Trie *p;
p = &root;
for (int i = 0; i< len; i++){
int id = str[i] - 'a';
p = p->next[id];
if (p == NULL) return 0;
}
return p->v;
}
int main()
{
char str[15];
int i;
for (i = 0; i< 26; i++)
root.next[i] = NULL;
while (gets(str) && str[0] != '\0')
creat(str);
memset(str,0,sizeof(str));
while (scanf ("%s",&str) != EOF){
int ans = search(str);
printf ("%d\n",ans);
}
return 0;
}
pku 1204
这一题我纠结了n久,本来改用AC自动机的(下一篇博客里讲),因为数据规模的原因,字典树都能暴过,而且由于我的AC自动机学的不怎么的,两个程序跑的时间差不多。。。。
/*
这一题用字典树纯属数据的原因,对所给的模式串建树,再对原图中每个节点的八个方向进行匹配,没有超时很是奇怪
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Trie{
int count;
struct Trie *fail;
struct Trie *next[26];
} *root,*queue[500005];
int n,m,result[1005][2];
char map[1005][1005],ans[1005];
int dir[8][2] = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void insert(char *s,int k)
{
int len = strlen(s),i;
struct Trie *p = root,*q;
for (i = 0; i< len; i++){
int id = s[i] - 'A';
if (p->next[id] == NULL){
q = (struct Trie *)malloc(sizeof(Trie));
memset(q->next,NULL,sizeof(q->next));
q->count = -1; p->next[id] = q; p = q;
}
else p = p->next[id];
}
p->count = k;
}
void search(int x,int y,int k)
{
int x1 = x,y1 = y;
struct Trie *p = root;
while (x1 >= 0 && y1 >= 0 && x1 < n && y1 < m){
int id = map[x1][y1] - 'A';
if (p->next[id] == NULL) break;
else p = p->next[id];
if (p ->count != -1){
result[p->count][0] = x; result[p->count][1] = y;
ans[p->count] = k + 'A'; p->count = -1;
}
x1 += dir[k][0]; y1 += dir[k][1];
}
}
void solve(int sum)
{
int i,j,k;
for (i = 0; i< n; i++)
for (j = 0; j< m; j++)
for (k = 0; k< 8; k++)
search(i,j,k);
for (i = 0; i < sum; i++)
printf ("%d %d %c\n",result[i][0],result[i][1],ans[i]);
}
int main()
{
int i,k;
char word[2005];
scanf ("%d%d%d",&n,&m,&k);
memset(map,0,sizeof(map));
root = (struct Trie *)malloc(sizeof(Trie));
memset(root->next,NULL,sizeof(root->next));
for (i = 0; i < n; i++) scanf ("%s",&map[i]);
getchar();
for (i = 0; i< k; i++){
gets(word);
insert(word,i);
}
solve(k);
return 0;
}
浙公网安备 33010602011771号