Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathBasic Calculator.java
More file actions
Latest commit
executable file
·154 lines (136 loc) · 4.67 KB
/
Copy pathBasic Calculator.java
File metadata and controls
executable file
·154 lines (136 loc) · 4.67 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
H
1526882596
tags: Stack, Math, ExpressionTree, BinaryTree, MinimumBinaryTree
给一个expressionString, 要evaluate这个expression的值.
Expressionstring里面包括 +, -, 整数, 开合括号, 还有space.
#### ExpressionTree
- ExpressionTree是一个weight-based的min-tree
- 基于运算符号 + 数字的tree: 数字永远在leaf, 然后符号是treenode, 括号不出现在tree里面
- 用monotonuousstack来构建这个tree
##### Thinkingpoints
- UnderstandExpressionTree
- Usestacktobuildtheexpressiontree + understandtheweightsystem
- Usepost-ordertraversaltoevaluatethetree
- 注意, input里面的数字不会是singledigit, 所以需要一个buffer存numberstring
- 整个题目的做法, 可以参照 `ExpressionEvaluation`
```
/*
Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ),
the plus + or minus sign -, non-negative integers and empty spaces .
You may assume that the given expression is always valid.
Some examples:
"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23
Note: Do not use the eval built-in library function.
*/
/*
build expression tree to evaluate expression
two functions:
1. build tree
parse string
skip space
identify operator
calculate weight of operator
add parentheses to base weight
2. evaluate with post-order traversal
*/
classSolution {
classTreeNode {
intweight;
Stringstr;
TreeNodeleft, right;
publicTreeNode(intweight, Stringstr) {
this.weight = weight;
this.str = str;
}
}
publicintcalculate(Strings) {
if (s == null || s.length() == 0) return0;
TreeNoderoot = buildTree(s); // build expression tree
return (int)evaluate(root); // post-order traversal of the tree
}
// build tree based on input string, min-tree. return root
privateTreeNodebuildTree(Strings) {
intn = s.length();
char[] chars = s.trim().toCharArray();
Stack<TreeNode> stack = newStack<>();
intbase = 0;
StringBuffersb = newStringBuffer();
for (inti = 0; i < n; i++) {
charc = chars[i];
if (c == ' ') {
continue;
} elseif (c == '(') { // '()' are used to add weight, not stored in tree
base = getWeight(base, c);
continue;
} elseif (c == ')') {
base = getWeight(base, c);
continue;
} elseif (i < n - 1 && isDigit(chars[i]) && isDigit(chars[i + 1])) { // continue to get remaining of the int
sb.append(c);
continue;
}
Stringstr;
if (isDigit(c)) {
sb.append(c);
str = sb.toString();
sb.setLength(0); // clean up
} else {
str = c + "";
}
// use monotonuous stack to build min-tree
TreeNodenode = newTreeNode(getWeight(base, c), str);
while (!stack.isEmpty() && node.weight <= stack.peek().weight) {
node.left = stack.pop();
}
if (!stack.isEmpty()) {
stack.peek().right = node;
}
stack.push(node);
}
TreeNoderoot = null;
while (!stack.isEmpty()) {
root = stack.pop();
}
returnroot; // it's the root of tree, always a operator
}
// post-order traversal to evaluate the expression
privatelongevaluate(TreeNoderoot) {
if (root == null) return0;
longleft = evaluate(root.left);
longright = evaluate(root.right);
longresult = 0;
switch(root.str) {
case"+":
result = left + right;
break;
case"-":
result = left - right;
break;
case"*":
result = left * right;
break;
case"/":
result = left / right;
break;
default:
result = Long.parseLong(root.str);
}
returnresult;
}
// get weight of the character. integer weights the most and will be leaf.
// Remember to store the result using long
privateintgetWeight(intbase, charc) {
if (c == '(') returnbase + 10;
if (c == ')') returnbase - 10;
if (c == '+' || c == '-') returnbase + 1;
if (c == '*' || c == '/') returnbase + 2;
returnInteger.MAX_VALUE;
}
privatebooleanisDigit(charc) {
returnc >= '0' && c <= '9';
}
}
```