poj 1056 字典树水题


刚刚做出来的

昨晚看的模板,第一次看懂了什么是字典树。。汗了,从一开始的结构体定义都不知道。。到现在A过了一题,嘿嘿,挺高兴的

写一下我的理解吧。

 

 

主要就是建立一堆一样的结构体,以ROOT为原点,*NEXT【10】为分支联络员,连接着OTHER们,如果输入的S字符串中的数没有建立,那就加一个OTHER【num++】为NEXT【数】的成员,最后再在END上画下true,表示结束。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct shu
{
 bool end;                                    //若END为true,说明以前有过这个字符串
 shu *next[10];                                               //next为分支联络员
};
shu root,other[10000];                             //建立一堆数OTHER ,root为原点
bool flag=true;                                            //flag为标志,初始为true,若找到重复的了,就标为false
char s[100];
int num=0;
void jianli(char s[])                                               //这个函数来建立各个小分支,并查找他们
{
 int len,i;
 len=strlen(s);
 shu *nowroot=&root;                                        //把原点ROOT给我新建立的NOWROOT  nowroot为当前的分支所在
 for(i=0;i<len;i++)                       //开始查找并建立了
 {
  if(nowroot->next[s[i]-'0']==NULL)                 //这一级若为空,开始建立
  {
   nowroot->next[s[i]-'0']=&other[num++];                //把OTHER [NUM++]的头地址给当前级的next【当前数】
   if(nowroot->end==true)                                           //如果当前级里的END为TRUE ,证明以前有过这个串了
    flag=false;                                                             // 把flag赋为false
  }
   nowroot=nowroot->next[s[i]-'0'];                             //把NOWROOT更新为下一级
 }
 if(i==len&&nowroot->end==true)                                 //如果当前查找的串有和以前一模一样的
  flag=false;                                                                    //flag赋为false
 nowroot->end=true;                                                             //for循环完了,把最后一个的下一个分支的END赋为true(现在的nowroot
                                                                                           //为最后一个串的下一级)
 for(i=0;i<10;i++)                                                                 //再来个循环看看有没有以前的更长的串,就是我现在的串比以前的短
 {
  if(nowroot->next[i]!=NULL)                                                //如果不为NULL,就证明有
  {
   flag=false;                                                                     //flag标为false
   break;
  }
 }
}
 
 
int main()
{
 int T=1,i;
 memset(other,0,sizeof(other));
 root.end=false;
 for(i=0;i<10;i++)
  root.next[i]=NULL;
 while(scanf("%s",s)!=EOF)
 {
  if(strcmp(s,"9")==0)
  {
   if(flag)                                                                                               //这个if 9 是个初始化
   printf("Set %d is immediately decodable\n",T++);
   else
   printf("Set %d is not immediately decodable\n",T++);
   memset(other,0,sizeof(other));
   flag=true;
   for(i=0;i<10;i++)
   root.next[i]=NULL;
   root.end=false;
  }
  else
   jianli(s);                                                                            //如果不是9,就建立并查找吧~
 }
 system("pause");
 return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值