算法入门经典-第六章 例题6-17 看图写树

 

 

题意:将多叉树转化为括号表示法,每个非叶结点的正下方都有一个'|'然后下方是一排'-'和字符,恰好覆盖所有子结点的正上方,单独的一行‘#’为数据的结束标志

解题思路:用gets将字符数组输入,本题不用建树,直接用广度优先递归求解,同时注意对空树的处理(需要单独判断),以及结点的符号不一定是字母,也可以是其他的符号(用isspace()判断是不是空格,并且单独判断是不是换行符'\0')

笔记:gets是从标准的输入接收一行字符,遇到'\n'时结束,但不接收'\n',把 '\n'留存输入缓冲区;把接收的一串字符存储在形式参数指针指向的空间,并在最后自动添加一个'\0'(因为不知道堆栈的大小,所以不安全)。fgets是从文件或标准输入接收一串字符,遇到'\n'时结束,把'\n'也作为一个字符接收;把接收的一串字符存储在形式参数指针指向的空间,并在'\n'后再自动添加一个'\0'。

 

#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=200+10;
int n;
char buf[maxn][maxn];
//递归便利并且输出以字符buf[r][c]为根的树 
void dfs(int r,int c){
    printf("%c(",buf[r][c]);
    if(r+1<n&&buf[r+1][c]=='|'){//有子树{ 
    int i=c;
     while(i-1>=0&&buf[r+2][i-1]=='-') i--;//找到"----"的左边界
     while(buf[r+2][i]=='-'&&buf[r+3][i]!='\0')
     {
         if(!isspace(buf[r+3][i])) dfs(r+3,i);//fgets读入的\n也满足isspace() //判断是否为空格,头文件<cctype>
         i++;
              } 
         }
     printf(")");
} 
void solve()
{
    n=0;
    for(;;){
        fgets(buf[n],maxn,stdin);
        if(buf[n][0]=='#') break;
        else n++;
        
    }
    printf("(");
    if(n){
        for(int i=0;i<strlen(buf[0]);i++)
        
        
            if(buf[0][i]!=' ') {dfs(0,i);break; 
            }
        
    }
    printf(")\n");
}
int main()
{
    int T;
    fgets(buf[0],maxn,stdin);
    sscanf(buf[0],"%d",&T);
    while(T--) solve();
    return 0;
} 

 

posted @ 2017-08-30 00:33  于繁华求淡然  阅读(271)  评论(0编辑  收藏  举报