【解题报告】百练2797_最短前缀(字典树)

来源:互联网 发布:seo公司哪家好 编辑:程序博客网 时间:2024/06/06 00:16

题目链接:http://bailian.openjudge.cn/practice/2797
总时间限制: 
1000ms 
内存限制: 
65536kB
描述
一个字符串的前缀是从该字符串的第一个字符起始的一个子串。例如 "carbon"的字串是: "c", "ca", "car", "carb", "carbo", 和 "carbon"。注意到这里我们不认为空串是字串, 但是每个非空串是它自身的字串. 我们现在希望能用前缀来缩略的表示单词。例如, "carbohydrate" 通常用"carb"来缩略表示. 现在给你一组单词, 要求你找到唯一标识每个单词的最短前缀
在下面的例子中,"carbohydrate" 能被缩略成"carboh", 但是不能被缩略成"carbo" (或其余更短的前缀) 因为已经有一个单词用"carbo"开始
一个精确匹配会覆盖一个前缀匹配,例如,前缀"car"精确匹配单词"car". 因此 "car" 是 "car"的缩略语是没有二义性的 , “car”不会被当成"carriage"或者任何在列表中以"car"开始的单词.
输入
输入包括至少2行,至多1000行. 每行包括一个以小写字母组成的单词,单词长度至少是1,至多是20.
输出
输出的行数与输入的行数相同。每行输出由相应行输入的单词开始,后面跟着一个空格接下来是相应单词的没有二义性的最短前缀标识符。
样例输入
carbohydratecartcarburetorcaramelcariboucarboniccartilagecarboncarriagecartoncarcarbonate
样例输出
carbohydrate carbohcart cartcarburetor carbucaramel caracaribou caricarbonic carbonicartilage carticarbon carboncarriage carrcarton cartocar carcarbonate carbona
#include <cstdio>#include <cstring>struct TNode{//字典树节点    int num;//该节点重复次数    TNode *next[26];//子节点    TNode(){        num=1;        for(int i=0;i<26;++i){            next[i]=NULL;        }    }};TNode *root;void Creat(char* s){//将s插入字典树中    int i=0;    TNode *p=root;    while(s[i]){        int k=s[i]-'a';        if(p->next[k]!=NULL) p->next[k]->num++;        else p->next[k]=new TNode;        p=p->next[k];        ++i;    }}void Find(char *s){   int i=0, x;   TNode *p = root;   while(p&&s[i]&&p->num>1)   {       x = s[i]-'a';       p = p->next[x];       putchar(s[i]);       i++;   }   printf("\n");}int main(){    //freopen("in.txt","r",stdin);    root=new TNode;    root->num=2;    char s[1010][30];    int i=0;    while(~scanf("%s",s[i])){        Creat(s[i]);        ++i;    }    for(int j=0;j<i;++j){        printf("%s ",s[j]);        Find(s[j]);    }    return 0;}

0 0
原创粉丝点击