您的位置:首页 > 其它

中缀表达式树及其结果计算

2017-03-26 22:25 113 查看
题目

给定一棵二叉树,二叉树的各个结点要么表示四则运算符+、-、*、/,要么表示一个不超过10的非负整数。将这棵二叉树看作中缀表达式树,输出对应的中缀表达式,以及该中缀表达式的计算结果。
注意,输出的中缀表达式中,除了最外层以外,内层的每个“左操作数 操作符 右操作数”形式的两侧都要加上一对小括号。例如2+(3*(4/5))就是一个可能的正确输出。

输入

每个输入文件中一组数据。
第一行一个正整数N(N<=30),代表二叉树的结点个数(结点编号为0到N-1)。
第二行按结点编号从小到大的顺序给出N个结点的值(用空格隔开),其要么是四则运算符+、-、*、/的其中一个,要么是一个不超过10的非负整数。
接下来按结点编号从小到大的顺序给出N行,每行为两个编号,分别代表该结点的左孩子编号和右孩子编号,如果不存在左(右)孩子,那么就用字符'-'代替。数据保证编号在0到N-1之间,且中缀表达式树一定是合法的。

输出

输出一行,即所求的中缀表达式与对应的计算结果(精度保留两位小数),表达式与计算结果之间用空格隔开。注意输出的中缀表达式中不允许有空格。数据保证中缀表达式合法,且计算过程中不会出现除数为0的情况。

输入样例

5

* 3 + 4 6

1 2

- -

3 4

- -

- -

输出样例

3*(4+6) 30.00

标程

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
using namespace std;
const int MAX = 30;
struct node{ //树结点
string data;
int lchild, rchild;
}Node[MAX];
int n;
bool isroot[MAX];

void create(){ //构造二叉树
cin >> n;
for (int i = 0; i < n; i++){
cin >> Node[i].data;
}
string str;
for (int i = 0; i < n; i++){
cin >> str;
if (str == "-"){ //左孩子为空
Node[i].lchild = -1;
}
else{
if (str.length() == 1){ //一位数
Node[i].lchild = str[0] - '0';
isroot[Node[i].lchild] = false; //左孩子为非根结点
}
else{ //两位数
Node[i].lchild = (str[0] - '0') * 10 + (str[1] - '0');
isroot[Node[i].lchild] = false; //左孩子为非根结点
}
}
cin >> str;
if (str == "-"){ //右孩子为空
Node[i].rchild = -1;
}
else{
if (str.length() == 1){//一位数
Node[i].rchild = str[0] - '0';
isroot[Node[i].rchild] = false; //右孩子非根
}
else{ //两位数
Node[i].rchild = (str[0] - '0') * 10 + (str[1] - '0');
isroot[Node[i].rchild] = false; //右孩子非根
}
}
}
}

int findroot(){ //找到根结点
for (int i = 0; i < n; i++){
if (isroot[i])
return i;
}
}

void inorder(int root){ //中序遍历并输出表达式
if (!(Node[root].data == "+" || Node[root].data == "-" || Node[root].data == "*" || Node[root].data == "/")){
cout << Node[root].data;
}
else{
cout << "(";
inorder(Node[root].lchild); //对左子树递归
cout << Node[root].data;
inorder(Node[root].rchild); //对右子树递归
cout << ")";
}
}

double cal(int root){ //计算某个节点的表达式值
if (!(Node[root].data == "+" || Node[root].data == "-" || Node[root].data == "*" || Node[root].data == "/")){ //数值结点即为根
if (Node[root].data.length() == 1) //返回数值
return Node[root].data[0] - '0';
else if (Node[root].data.length() == 2)
return (Node[root].data[0] - '0') * 10 + (Node[root].data[1] - '0');
}
else if (Node[root].data == "+")return cal(Node[root].lchild) + cal(Node[root].rchild); //用左子树的结果和右子树结果计算
else if (Node[root].data == "-")return cal(Node[root].lchild) - cal(Node[root].rchild);
else if (Node[root].data == "*")return cal(Node[root].lchild) * cal(Node[root].rchild);
else if (Node[root].data == "/")return cal(Node[root].lchild) / cal(Node[root].rchild);
}

int main(){
fill(isroot, isroot + MAX, true); //初始化根标志数组
create(); //构造树
int root = findroot(); //找到根
inorder(Node[root].lchild); //因最外层无括号单独处理根结点
cout << Node[root].data;
inorder(Node[root].rchild);
printf(" ");
printf("%.2f", cal(root)); //对根计算并输出
cin >> n; //调试用观察输出
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: