poj 1056 字典樹水題
阿新 • • 發佈:2019-01-31
剛剛做出來的
昨晚看的模板,第一次看懂了什麼是字典樹。。汗了,從一開始的結構體定義都不知道。。到現在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; }