|
| 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