我是靠谱客的博主 彪壮睫毛,这篇文章主要介绍你们要的中缀表达式树,现在分享给大家,希望可以做个参考。

你们要的中缀表达式树
Case Time Limit: 100 MS (Others) / 200 MS (Java) Case Memory Limit: 256 MB (Others) / 512 MB (Java)
Accepted: 32 Total Submission: 141
查看我的提交显示标签
Problem Description
给定一棵二叉树,二叉树的各个结点要么表示四则运算符+、-、*、/,要么表示一个不超过10的非负整数。将这棵二叉树看作中缀表达式树,输出对应的中缀表达式,以及该中缀表达式的计算结果。
注意,输出的中缀表达式中,除了最外层以外,内层的每个“左操作数 操作符 右操作数”形式的两侧都要加上一对小括号。例如2+(3*(4/5))就是一个可能的正确输出。
Input
每个输入文件中一组数据。
第一行一个正整数N(N<=30),代表二叉树的结点个数(结点编号为0到N-1)。
第二行按结点编号从小到大的顺序给出N个结点的值(用空格隔开),其要么是四则运算符+、-、*、/的其中一个,要么是一个不超过10的非负整数。
接下来按结点编号从小到大的顺序给出N行,每行为两个编号,分别代表该结点的左孩子编号和右孩子编号,如果不存在左(右)孩子,那么就用字符’-‘代替。数据保证编号在0到N-1之间,且中缀表达式树一定是合法的。
Output
输出一行,即所求的中缀表达式与对应的计算结果(精度保留两位小数),表达式与计算结果之间用空格隔开。注意输出的中缀表达式中不允许有空格。数据保证中缀表达式合法,且计算过程中不会出现除数为0的情况。
Sample Input
5
* 3 + 4 6
1 2
- -
3 4
- -
- -
Sample Output
3*(4+6) 30.00
Author
Shoutmon
Source
17浙大考研机试模拟赛

思路,中缀表达式很好球,建树后直接中序遍历即可,然后去掉最外层括号,用string很容易实现,难点在于求值,因为题目中数值大于等于0小于等于10,所以可能出现两位,因此可以用char存储数值和计算符号,本次实现借助了flag来判断是否为运算符,因此代码比较多,可以将数值也存到char中, 这里不做阐述

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#define _CRT_SECURE_NO_WARNINGS #include <algorithm> #include <iostream> #include <sstream> #include <iomanip> #include <cstring> #include <string> using namespace std; const int MaxN = 36; int N; struct node { int data; bool sign; char s; int lchild; int rchild; node() { rchild = lchild = -1; sign = false; } }Node[MaxN]; bool isRoot[MaxN]; string res; string IntToStr(int num) { string str; while (num) { str.insert(str.begin(),num % 10 + '0'); num /= 10; } if (!str.size()) return "0"; return str; } double post(int root) { if (-1 == root) return 0; bool flag = (Node[root].lchild != -1 || Node[root].rchild != -1); if (flag) res += "("; double leftv = post(Node[root].lchild); if (Node[root].sign) res += Node[root].s; else res += IntToStr(Node[root].data); double rightv = post(Node[root].rchild); if (flag) res += ")"; if (!Node[root].sign) return Node[root].data; else { switch (Node[root].s) { case '+':return leftv + rightv; case '-':return leftv - rightv; case '*':return leftv * rightv; case '/':return leftv / rightv; default: return 0; } } } int main() { #ifdef _DEBUG freopen("data.txt", "r+", stdin); #endif // _DEBUG std::ios::sync_with_stdio(false); stringstream ss; string str; int idx = 0; cin >> N; cin.get(); getline(cin, str); ss << str; for (int i = 0; i < N; ++i) { if ('0' <= str[idx] && str[i] <= '9') { ss >> Node[i].data; } else { char ch; ss >> ch; Node[i].s = ch; Node[i].sign = true; } while (idx < str.size()-1 && str[idx] != ' ')++idx; if (idx < str.size() - 1) ++idx; } memset(isRoot, 1, N + 1); for (int i = 0; i < N; ++i) { ss.clear(); ss.str(""); getline(cin, str); ss << str; int idx = 0, lc, rc; if (str[idx] == '-') { ss.get(); ++idx; } else { ss >> Node[i].lchild; isRoot[Node[i].lchild] = false; } while (str[idx] != ' ')++idx; ++idx; if (str[idx] != '-') { ss >> Node[i].rchild; isRoot[Node[i].rchild] = false; } } int root = 0; while (!isRoot[root])++root; double val = post(root); if (res.size() >= 3) { res.erase(res.begin()); res.erase(res.end()-1); } cout << res << " " ; cout << setiosflags(ios::fixed) << setprecision(2) << val; return 0; }

最后

以上就是彪壮睫毛最近收集整理的关于你们要的中缀表达式树的全部内容,更多相关你们要内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部