標籤:uva 遞迴 樹
題目:題目就是給出一幅ASCII字元構成的樹的圖,然後轉換成由字元括弧構成的樹的表示形式。可以知道,樹有孩子結點的話,正下方會有一個字元 ‘|‘ ,緊接著會有一個覆蓋所有孩子結點的字元序列“-------”,然後其下就是孩子結點。
思路:先將所有資料讀下來。然後遞迴處理,給定一個左右邊界,在該邊界內逐個檢查字元,如果是結點字元,則判斷有無孩子等後續處理。
注意:因為每行會有空格,所以不能用scanf輸入,換成fgets的話會保留有分行符號(當然,可以進行處理或後續判斷),這裡使用的是gets來讀入,因為可以確保不會溢出。
另外,由scanf改為gets後需要在讀第一個整數後來個getchar棄掉分行符號。發現每次改輸入時都容易有這個問題,下次改輸入時要注意。gets和scanf搭配時要注意分行符號的問題。
另外,這裡不要認為字串每次都會重新讀入,就不用memset初始化了;如果新的資料行數比舊的少,殘留的資料還是可能影響到的,因為你有檢查h+1和h+2而且沒有對其是否超過總行數進行判斷。
另外,由於數組中其他字元為‘\0‘,所以在判斷是否為結點字元時加入了不等於Null 字元這一項。(當然,你可以通過給定的是嚴格的左右範圍,來處理Null 字元這個問題)
吐槽:由於沒把freopen注釋掉,導致WA了,還以為是加入不等於Null 字元導致的~~
遞迴是個好東西,最近幾次寫的比較多~
終於做完二叉樹小專題的了~感覺比做線性表的還快一點啊~
Code:
#include<stdio.h>#include<string.h>#define MAXN 210void dfs(int h,int left,int right);char tree[MAXN][MAXN];int main(){ //freopen("10562.in","r",stdin); //freopen("10562.out","w",stdout); int t; scanf("%d",&t); getchar();//棄了分行符號,不是在while內。。 while(t-->0) { int hs=0; memset(tree,0,sizeof(tree));//不要認為有gets輸入了就不memset了,舊資料有可能影響到。 while(gets(tree[hs])!=NULL && tree[hs++][0]!='#'); dfs(0,0,MAXN); printf("\n"); } return 0; }void dfs(int h,int left,int right){ printf("("); for(int i=left;i<right;++i) { char c=tree[h][i]; if(c!='-' && c!='|' && c!=' ' && c!='#' && c!='\0') {//是一結點字元 printf("%c",c); if(tree[h+1][i]=='|') {//有孩子 int x=i-1; while(tree[h+2][x]=='-') x--; //x++; //不需要這句,因為for迴圈中是<right,不是小於等於 int y=i+1; while(tree[h+2][y]=='-') y++; //y--; dfs(h+3,x,y); } else printf("()");//printf("%c:()",c); } }//for printf(")"); }
UVa 10562 看圖寫樹