poj 2001字典树

题目: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;  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值