题目:http://poj.org/problem?id=2001
题意:找最长公共前缀符,再加一个字母,组成能唯一识别自身单词的新缩写
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int MAX=26;
char str[1000][21],res[1000][21];
struct node{
struct node *next[MAX]; //字母分支
int flag; //字母出线过的次数统计
}node;
struct node *root; //根节点
void inset_tree(char *str) //插入字符串
{
int ans,i,len;
struct node *p,*q;
p=root; //p先指向根节点
len=strlen(str);
for(i=0;i<len;i++){
ans=str[i]-'a'; //每一个字母的字母编号
if(p->next[ans]!=NULL) //如果非空
{
p=p->next[ans]; //p指向该字母节点
p->flag++; //该字母出现过的次数加1
}
else{
q=(struct node*)calloc(1,sizeof(node)); //创建新节点
p->next[ans]=q; //q赋给该节点
p=q; //p指向该节点
p->flag=1; //节点数为1
}
}
}
void find(char *str,char *res) //查找
{
int len,ans,i;
struct node *p;
p=root;
len=strlen(str);
for(i=0;i<len;i++){
ans=str[i]-'a';
p=p->next[ans]; //p指向该字母节点
res[i]=str[i]; //该字母赋给结果数组
if(p->flag==1) //如果该字母是这个字符串所独有的
{
res[++i]='\0'; //查找完成
return ;
}
}
}
int main(){
int n=0,i;
root=(struct node *)calloc(1,sizeof(node));
while(scanf("%s",str[n])!=EOF) //插入输入的每一个字符串
{
inset_tree(str[n]);
n++;
}
for(i=0;i<n;i++) //查找每一个字符串的最短有效前缀
find(str[i],res[i]);
for(i=0;i<n;i++)
printf("%s %s\n",str[i],res[i]);
return 0;
}