题目意思: 给定一个多叉树的图,要求把图转化为一颗树,最后输出相应的内容。
解题思路: 1 建树 + 前序遍历输出 。这题的输入就是一个很麻烦的事了,我是采用一个二维的char数组来存储读入的图,但是建树的过程我花了一天的时间一直没有成功,不懂为什么(本人比较菜逼)
2 递归输出 。对于题目的输入其实就是一颗已经建好的树,我么只需要去找到对应的子树然后搜索去输出即可,学会使用递归很重要,可以很简便的写出代码
代码:
//题目给的一个图其实就是树了,那么我们就不用去建树了,建树是个很繁琐的事情,那么我们知道对于这颗树,我么可以去搜素它,如果遇到有子树就继续往下去搜索直到叶子节点,一个dfs就可以(注意这一题的子树最多有200个,那么我们必须一个一个的找到左边的位置和右边的位置,否则出错)。1 注意输入的字符是所有的ASCII字符,2 还要注意有可能是空树的情况 3 左括号等于右括号,对于叶子节点后面是一个(); #include <iostream> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 250; int t, cnt, flag; char G[MAXN][MAXN]; //初始化函数(避免后面可能会越界用到前面的数据,那么只要初始化为空格即可) void init(){ for(int i = 0 ; i < MAXN ; i++){ for(int j = 0 ; j < MAXN ; j++) G[i][j] = ' '; } } //判断当前节点是否满足 int judge(char c) { if (c != '-' && c != '|' && c != ' ')//只要不是这三个字符均满足条件 return 1; return 0; } //递归输出这颗树 void dfs(int k, int l, int r) {//k是第k行,l是左边的起始点,r是右边的终点 if (k < cnt) {//k满足条件才递归 int i, j; printf("(");//先大印一个“(" for (i = l ; i <= r && i < strlen(G[k]) ; i++) {//从左边到右边去遍历子树 if (judge(G[k][i])) {//满足条件前提 printf("%c", G[k][i]);//打印字母 if (G[k+1][i] == '|') {//判断是否有子树 for (j = i ; G[k+2][j] == '-' && j > 0 ; j--);//找子树的左边起点 int templ = j; for (j = i ; G[k+2][j] == '-' && j < strlen(G[k+2])-1 ; j++);//找子树的右边终点 int tempr = j; dfs(k + 3, templ, tempr);//继续搜索子树 } else printf("()");//如果没有子树说明到了叶子节点,那么要输出一个“()”; } } printf(")");//遍历完一颗子树就要输出“)” } } //输入处理以及函数的调用 int main() { //freopen("input.txt", "r", stdin); scanf("%d%*c", &t); while (t--) { int i = 0; init(); while (gets(G[i])) { if (G[i][0] == '#') break; ++i; } cnt = i; if (cnt == 0)//如果是空树就输出()即可 printf("()\n"); else { dfs(0, 0, strlen(G[0])-1);//递归调用,开始的左边是0 右边是strlen(G[0]-1); printf("\n"); } } return 0; }