1. 程式人生 > >poj 1056 字典樹水題

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;
}