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]='