中缀表达式树及其结果计算
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;
}
给定一棵二叉树,二叉树的各个结点要么表示四则运算符+、-、*、/,要么表示一个不超过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;
}
相关文章推荐
- 【综合】中缀表达式转换成后缀表达式后,用后缀表达式计算出结果
- 中缀表达式转后缀表达式及其计算
- 计算A+B及其结果的标准形式输出
- java 计算中缀表达式结果
- 中缀表达式转后缀表达式并输出计算结果
- C语言::将中缀表达式转换为后缀表达式并计算结果
- Java实现中缀表达式转后缀表达式并计算结果
- 数据结构实现中缀表达式到后缀表达式,再到计算出结果的代码
- 中缀表达式转为后缀表达式,并计算结果
- 中缀表达式转后缀表达式并计算结果
- 学习日志-中缀表达式转后缀表达式并计算结果
- 【中缀表达式转后缀表达式&&输出计算结果】
- 中缀表达式转后缀表达式并计算
- 关于加权平均、队列、算术平均对计算对结果的影响
- 【java学习记录】11.用多线程实现阶乘的计算过程和结果的读取(thread类ReadThread )
- 在excel中编辑了公式之后,计算结果总要保存后才能显示,请问修改哪里可以实时地显示公式计算结果?
- C/C++ 编程计算2的100万次方(m的n次方),超长结果输出文件
- Delphi的实数计算结果中只保留2位小数
- Fibonacci 数列及其计算方法
- c++中缀表达式转后缀表达式并计算