Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. #include <iostream>
  2. #include <memory>
  3. #include <stack>
  4. #include <vector>
  5. #include <string>
  6. #include <cstdint>
  7.  
  8. using namespace std;
  9.  
  10. // Внимание!
  11. // Для простоты разбора будем использовать только числа из одной цифры,
  12. // а также не будет скобок, пробелов и ненужных символов.
  13. // При этом, будем считать, что выражение всегда корректно.
  14.  
  15. struct Node {
  16.   virtual int Evaluate() const = 0;
  17. };
  18.  
  19. struct Value : public Node {
  20.   Value(char digit) : _value(digit - '0') {}
  21.  
  22.   int Evaluate() const override { return _value; }
  23.  
  24. private:
  25.   const uint8_t _value;
  26. };
  27.  
  28. struct Variable : public Node {
  29.   Variable(const int &x) : _x(x) {}
  30.  
  31.   int Evaluate() const override { return _x; }
  32.  
  33. private:
  34.   const int &_x;
  35. };
  36.  
  37. struct Op : public Node {
  38.   Op(char value)
  39.       : precedence([value] {
  40.           if (value == '*') {
  41.             return 2;
  42.           } else {
  43.             return 1;
  44.           }
  45.         }()),
  46.         _op(value) {}
  47.  
  48.   const uint8_t precedence;
  49.  
  50.   int Evaluate() const override {
  51.     if (_op == '*') {
  52.       return _left->Evaluate() * _right->Evaluate();
  53.     } else if (_op == '+') {
  54.       return _left->Evaluate() + _right->Evaluate();
  55.     } else if (_op == '-') {
  56.       return _left->Evaluate() - _right->Evaluate();
  57.     }
  58.  
  59.     return 0;
  60.   }
  61.  
  62.   void SetLeft(shared_ptr<Node> node) { _left = node; }
  63.   void SetRight(shared_ptr<Node> node) { _right = node; }
  64.  
  65. private:
  66.   const char _op;
  67.   shared_ptr<const Node> _left, _right;
  68. };
  69.  
  70. template <class Iterator>
  71. shared_ptr<Node> Parse(Iterator token, Iterator end, const int &x) {
  72.   // Empty expression
  73.   if (token == end) {
  74.     return make_shared<Value>('0');
  75.   }
  76.  
  77.   stack<shared_ptr<Node>> values;
  78.   stack<shared_ptr<Op>> ops;
  79.  
  80.   auto PopOps = [&](int precedence) {
  81.     while (!ops.empty() && ops.top()->precedence >= precedence) {
  82.       auto value1 = values.top();
  83.       values.pop();
  84.       auto value2 = values.top();
  85.       values.pop();
  86.       auto op = ops.top();
  87.       ops.pop();
  88.  
  89.       op->SetRight(value1);
  90.       op->SetLeft(value2);
  91.  
  92.       values.push(op);
  93.     }
  94.   };
  95.  
  96.   while (token != end) {
  97.     const auto &value = *token;
  98.     if (value >= '0' && value <= '9') {
  99.       values.push(make_shared<Value>(value));
  100.     } else if (value == 'x') {
  101.       values.push(make_shared<Variable>(x));
  102.     } else if (value == '*') {
  103.       PopOps(2);
  104.       ops.push(make_shared<Op>(value));
  105.     } else if (value == '+' || value == '-') {
  106.       PopOps(1);
  107.       ops.push(make_shared<Op>(value));
  108.     }
  109.  
  110.     ++token;
  111.   }
  112.  
  113.   while (!ops.empty()) {
  114.     PopOps(0);
  115.   }
  116.  
  117.   return values.top();
  118. }
  119.  
  120. int main() {
  121.   string tokens;
  122.   cout << "Enter expression: ";
  123.   getline(cin, tokens);
  124.  
  125.   int x = 0;
  126.   auto node = Parse(tokens.begin(), tokens.end(), x);
  127.  
  128.   cout << "Enter x: ";
  129.   while (cin >> x) {
  130.     cout << "Expression value: " << node->Evaluate() << endl;
  131.     cout << "Enter x: ";
  132.   }
  133.  
  134.   return 0;
  135. }a
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement