字典树,HDU1075

http://acm.hdu.edu.cn/showproblem.php?pid=1075

字典树的简单运用,这题关键在于处理相同后缀的问,只要在结点里加个标志就可以了,标志到此结点为止是否已经有可代换的单词

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node
{
    struct node *child[26];//这是接下去的字母的指针 
    char v[100];//存储信息,可变。这里存的是以到此为止的字符串为前缀的单词量 
    int n;
}Trie;
Trie *root;
int build(char *I,char *M)
{
    int len=strlen(M),i,j;
    Trie *s,*l;
    if(len==0)return 0;
    s=root;
    for(i=0;i<len;i++)
    {
        if(s->child[M[i]-'a']==NULL)//当接下去的的指针为空时,新申请一个节点出来,存储信息, 
        {
            l=(Trie *)malloc(sizeof(Trie));
            l->n=0;//初始化是
            for(j=0;j<26;j++)
              l->child[j]=NULL;
            s->child[M[i]-'a']=l;//往下走 
            s=l;
        }
        else {
                s=s->child[M[i]-'a'];//这里因为在根结点处为存储东西,所以要先找到下个结点,然后再进行信息的更新 
             }
    }
    s->n=1;
    strcpy(s->v,I);
}
char *find(char str[])
{
    int i,len=strlen(str);
    Trie *s=root;
    for(i=0;i<len;i++)
       {
       if(s->child[str[i]-'a'])//在有连接的情况下才往下走 
         s=s->child[str[i]-'a'];
       else return str;//单词没找到就返回0,否则返回答案 
       }
    if(s->n)//标志到这里是否已经有单词可代换 
    return s->v;//
    else return str;
}

int main()
{
    int i,len,j;
    char s[50],k[50],zong[5000];
    root=(Trie *)malloc(sizeof(Trie));
    for(i=0;i<26;i++)
      root->child[i]=NULL;
    root->n=0;//初始化为0; 
    scanf("%s",s);
    while(1)
    {
      scanf("%s",s);
      if(strcmp(s,"END")==0)break;
      scanf("%s",k);
      build(s,k);
    }
    scanf("%s",s);
    gets(zong);
    while(gets(zong),strcmp(zong,"END"))
    {
       len=strlen(zong);
       for(i=0;i<len;i++)
       {
          if(zong[i]>='a'&&zong[i]<='z')
          {
             j=0;
             for(;zong[i]>='a'&&zong[i]<='z';i++)
               s[j++]=zong[i];//单词拆分 
             i--;
             s[j]='';
             printf("%s",find(s));
          }
          else printf("%c",zong[i]);
       }
       printf("
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/huzhenbo113/p/3217078.html