要求
我们给出一个表达式,将它转化为逆波兰式,传给树求值,例如1+2+3 转化为 12+3+
做法
匹配:
初始化一个栈stack,然后遍历这个逆波兰式的字符串,如果遇到数字,则以这个数字的值生成一个新的树节点,将这个节点入栈;如果遇到操作符,就以操作符为值生成一个新的树节点,弹栈弹出一个节点作为该新节点的右孩子节点,再弹出一个节点作为该新节点的左孩子节点,最后将该新节点入栈。遍历结束后,判断栈里的元素个数是否为1,如果为1则匹配成功;如果不为1则逆波兰式是非法的。
求值:
遍历树进行求值,具体做法看代码。
代码实现
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
| #include <iostream>
#include <stack>
using namespace std;
struct treeNode{
char val;
treeNode* left;
treeNode* right;
treeNode(char val){
this->val = val;
this->left = nullptr;
this->right = nullptr;
}
};
class BSTree{
treeNode* root;
public:
BSTree(){
root = nullptr;
}
/**
*解析表达式字符串
**/
void parse(char str[]){
const char* p = str;
stack<treeNode*> stack;
while (*p != '\0') {
if (*p>='0' && *p<='9') {
stack.push(new treeNode(*p));
}else{
treeNode* newNode = new treeNode(*p);
treeNode* rightNode = stack.top();
stack.pop();
newNode->right = rightNode;
treeNode* leftNode = stack.top();
stack.pop();
newNode->left = leftNode;
stack.push(newNode);
}
p++;
}
if (stack.size()!=1) {
cout<<"Illegal expression";
root = nullptr;
}else{
root = stack.top();
}
}
/**
*计算表达式的值
**/
int evaluate(){
if (root==nullptr) {
cout<<" ";
//如果表达式不规范返回int最小值
return numeric_limits<int>::min();
}else{
return evaluate(root);
}
}
private:
int evaluate(treeNode* node){
switch (node->val) {
case '+':
return evaluate(node->left)+evaluate(node->right);
case '-':
return evaluate(node->left)-evaluate(node->right);
case '*':
return evaluate(node->left)*evaluate(node->right);
case '/':
return evaluate(node->left)/evaluate(node->right);
;
//叶子节点
default:
return node->val - '0';
;
}
}
};
int main(int argc, const char * argv[]) {
BSTree tree;
tree.parse("44+22+/");
cout<<tree.evaluate()<<endl;
return 0;
}
|