题意:根据给定的图树, 输出对应的括号树。树的结点可以是任意可打印的字符, 不包括'|' 、'-'、 '#' '、 ' '\0'、 '\n'。 对于\n 其实我是看别人题解的。那句英语折磨死我了。
思路:关键在于递归建树。用二维char数组一次性读掉整张图。因为是不定叉, 所以用vector保存孩子结点。具体如下:
特殊处理第一行(可能为空树), 找到根结点的坐标开始递归。 对于每一个有效的结点字符, 都要构建一个结点, 然后返回它自己。如果它的下一行是'|' 说明它有孩子,则在返回之前要往下递归建树。找到分割线'-----'的线头 for下去, 如果分割线在下一行一有 结点字符就再建树, 每返回的一个结点指针 childs.push_back(孩子结点指针); (vector<Node *> childs;)
算法复杂度: o(N), N是结点数。
代码:
#include <cstdio>
#include <vector>
#include <cstring>
#include <cctype>
using namespace std;
#define MAX_LINE 220
#define MAX_CHAR 220
struct Node
{
char ch;
vector<Node *> childs;
};
char pfTree[MAX_LINE][MAX_CHAR];
Node *root;
Node *mkTree(int, int);
void rmTree(Node *&);
void printOurTree(Node *);
bool isNode(char);
int main()
{
int cases;
scanf("%d%*c", &cases);
while (cases--) {
// init
memset(pfTree, 0, sizeof(pfTree));
root = NULL;
// enter
for (int i = 0; i < MAX_LINE; i++) {
gets(pfTree[i]);
if (pfTree[i][0] == '#') {
break;
}
}
// make tree
if (pfTree[0][0] == '#') {
printf("()\n");
} else {
int y;
for (int i = 0; i < MAX_CHAR; i++) {
if (isNode(pfTree[0][i])) {
y = i;
break;
}
}
root = mkTree(0, y);
// printf
printf("(");
printOurTree(root);
printf(")\n");
// remove tree
rmTree(root);
}
}
return 0;
}
Node *mkTree(int row, int col)
{
Node *root = new Node;
root->ch = pfTree[row][col];
// child ?
int verticalRow = row + 1;
if (pfTree[verticalRow][col] == '|') {
int head;
int lineRow = row + 2;
for (head = col; head >= 0; head--) {
if (pfTree[lineRow][head] != '-') {
break;
}
}
head++;
int chilRow = row + 3;
for (int i = head; pfTree[lineRow][i] == '-'; i++) {
if (isNode(pfTree[chilRow][i])) {
root->childs.push_back(mkTree(chilRow, i));
}
}
}
return root;
}
void rmTree(Node *&root)
{
int size = root->childs.size();
for (int i = 0; i < size; i++) {
rmTree(root->childs[i]);
}
delete root;
root = NULL;
}
void printOurTree(Node *root)
{
printf("%c", root->ch);
int size = root->childs.size();
if (size != 0) {
printf("(");
for (int i = 0; i < size; i++) {
printOurTree(root->childs[i]);
}
printf(")");
} else {
printf("()");
}
}
bool isNode(char ch)
{
if (ch == '-') {
return false;
} else if (ch == '|') {
return false;
} else if (ch == ' ') {
return false;
} else if (ch == '\n') {
return false;
} else if (ch == '\0') {
return false;
} else if (ch == '#') {
return false;
} else {
return true;
}
}