杭电1075——What Are You Talking About(字典树应用)

来源:互联网 发布:java对string排序 编辑:程序博客网 时间:2024/05/04 22:30

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1075

主要算法:
一开始使用数组存储英文和对应的火星文,排序,再折半查找,结果超时。后来,百度了下,改成用字典树存储。其典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

字典树的数据结构

# define MAX 26typedef struct Trie{    struct Trie *next[MAX];    char *eng;//此处可以根据需要修改}Trie;

由于题中限定只有小写字母,所以MAX为26。如果是大小写字母,则MAX为52。如果是大小写字母和数字,则MAX为62。next是指向下一层的指针数组,设一节点为p。若p->next[k]==NULL,则该节点下一层没有’a’+k的节点,如果p->next[k]!=NULL,则说明该节点下一层有’a’+k的节点。该结构中的char *eng,可以根据题意修改。此题需要记录火星文对应的英文,所以,设置一个eng。当在一个火星文单词的末端节点的eng中存储了其对应的英文,其余情况下,eng为NULL。

这里写图片描述

字典树的查找:
(1) 每次从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;  
(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。   
(4) 迭代过程……   
(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。

AC代码

# include<stdio.h># include<stdlib.h># include<string.h># define MAX 26typedef struct Trie{    struct Trie *next[MAX];    char *eng;}Trie;Trie * root=NULL;char word[30010];void transOneLine();void insertTrie(char str1[],char str2[]);void translate();int main(){    translate();    return 0;}void translate(){    int i;    root=(Trie *)malloc(sizeof(Trie));    for(i=0;i<MAX;i++)        root->next[i]=NULL;    root->eng=NULL;    //输入单词,建立字典树    char str1[12],str2[12];    while(1)    {        scanf("%s",str1);        if(strcmp(str1,"START")==0)            continue;        else if(strcmp(str1,"END")==0)            break;        scanf("%s",str2);        insertTrie(str1,str2);    }    getchar();//避免gets把换行读成一个空行    //输入要翻译的文字    while(1)    {        gets(word);        if(strcmp(word,"START")==0)            continue;        else if(strcmp(word,"END")==0)            break;        transOneLine();        printf("\n");    }}void insertTrie(char str1[],char str2[]){    if(!root)        return;    Trie *p=root;    int len=strlen(str2),i,j;    for(i=0;i<len;i++)    {        int k=str2[i]-'a';        if(p->next[k]==NULL)        {            p->next[k]=(Trie *)malloc(sizeof(Trie));            p->eng=NULL;            p=p->next[k];            for(j=0;j<MAX;j++)                p->next[j]=NULL;        }        else            p=p->next[k];    }    p->eng=(char *)malloc(sizeof(char)*12);    strcpy(p->eng,str1);}void transOneLine(){    int j;    char temp[12];        for(j=0;word[j]!='\0';)        {            int k=0;            while(word[j]>='a'&&word[j]<='z')            {                temp[k++]=word[j++];            }            temp[k]='\0';            if(k>0)            {                Trie * p=root;                int t;                for(t=0;t<k;t++)                {                    int id=temp[t]-'a';                    if(p->next[id]==NULL)                        break;                    p=p->next[id];                }                if(t==k&&p->eng)                    printf("%s",p->eng);                else                    printf("%s",temp);            }            while((word[j]<'a'||word[j]>'z')&&word[j]!='\0')                printf("%c",word[j++]);    }}
0 0
原创粉丝点击