Skip to content

Commit 0fc84b8

Browse files
authored
Create design-an-expression-tree-with-evaluate-function.cpp
1 parent d1d07dc commit 0fc84b8

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Time: O(n)
2+
// Space: O(h)
3+
4+
#define ITER
5+
6+
class Node {
7+
public:
8+
virtual ~Node () {};
9+
virtual int evaluate() const { return 0; };
10+
protected:
11+
};
12+
13+
class NodeIter : public Node {
14+
public:
15+
NodeIter (int val) : val(val) {};
16+
NodeIter (char op, NodeIter *left, NodeIter *right) : op(op), left(left), right(right) {};
17+
virtual ~NodeIter () {};
18+
virtual int evaluate() const {
19+
int result = 0;
20+
vector<tuple<int, NodeIter *, unique_ptr<int>, unique_ptr<int>, int*>> stk;
21+
stk.emplace_back(1, const_cast<NodeIter *>(this), nullptr, nullptr, &result);
22+
while (!empty(stk)) {
23+
const auto [step, node, ret1, ret2, ret] = move(stk.back()); stk.pop_back();
24+
if (step == 1) {
25+
if (node->op == 0) {
26+
*ret = node->val;
27+
continue;
28+
}
29+
auto ret1 = make_unique<int>(), ret2 = make_unique<int>();
30+
auto p1 = ret1.get(), p2 = ret2.get();
31+
stk.emplace_back(2, node, move(ret1), move(ret2), ret);
32+
stk.emplace_back(1, node->right, nullptr, nullptr, p2);
33+
stk.emplace_back(1, node->left, nullptr, nullptr, p1);
34+
} else if (step == 2) {
35+
int l = *ret1, r = *ret2;
36+
*ret = (node->op == '+') ? l + r :
37+
(node->op == '-') ? l - r :
38+
(node->op == '*') ? l * r :
39+
(node->op == '/') ? l / r : 0;
40+
}
41+
}
42+
return result;
43+
}
44+
45+
public:
46+
int val;
47+
char op = 0;
48+
NodeIter *left = nullptr;
49+
NodeIter *right = nullptr;
50+
};
51+
52+
class NodeRecu : public Node {
53+
public:
54+
NodeRecu (int val) : val(val) {};
55+
NodeRecu (char op, NodeRecu *left, NodeRecu *right) : op(op), left(left), right(right) {};
56+
virtual ~NodeRecu () {};
57+
virtual int evaluate() const {
58+
if (op == 0) {
59+
return val;
60+
}
61+
int l = left->evaluate(), r = right->evaluate();
62+
return (op == '+') ? l + r :
63+
(op == '-') ? l - r :
64+
(op == '*') ? l * r :
65+
(op == '/') ? l / r : 0;
66+
}
67+
68+
public:
69+
int val;
70+
char op = 0;
71+
NodeRecu *left = nullptr;
72+
NodeRecu *right = nullptr;
73+
};
74+
75+
76+
class TreeBuilder {
77+
public:
78+
Node* buildTree(vector<string>& postfix) {
79+
#ifdef ITER
80+
using TreeNode = NodeIter;
81+
#else
82+
using TreeNode = NodeRecu;
83+
#endif
84+
vector<Node *> stk;
85+
for (const auto& s : postfix) {
86+
if (isdigit(s[0])) {
87+
stk.emplace_back(new TreeNode(stoi(s)));
88+
} else {
89+
auto right = dynamic_cast<TreeNode*>(stk.back()); stk.pop_back();
90+
auto left = dynamic_cast<TreeNode*>(stk.back()); stk.pop_back();
91+
stk.emplace_back(new TreeNode(s[0], left, right));
92+
}
93+
}
94+
return stk.back();
95+
}
96+
};

0 commit comments

Comments
 (0)