Advertisement
Sanlover

Untitled

Oct 18th, 2021
926
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.60 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. using namespace std;
  5.  
  6. static const string kOperators = "+-*/";
  7.  
  8. string getClean(string str) {
  9.   for (string::iterator it = str.begin(); it != str.end(); ++it) {
  10.     while (*it == ' ') {
  11.       it = str.erase(it);
  12.     }
  13.   }
  14.   return str;
  15. }
  16.  
  17. vector<size_t> getBalanced(const string& expression) {
  18.   vector<size_t> result(expression.size());
  19.  
  20.   size_t layerId = 0;
  21.   for (size_t i = 0; i < expression.size(); i++) {
  22.     if (expression[i] == '(') {
  23.       layerId++;
  24.       result[i] = layerId;
  25.     } else if (expression[i] == ')') {
  26.       result[i] = layerId;
  27.       layerId--;
  28.     } else {
  29.       result[i] = layerId;
  30.     }
  31.   }
  32.  
  33.   return result;
  34. }
  35.  
  36. bool fitBalance(vector<size_t>& balance) {
  37.   bool isFound = false;
  38.   for (auto& it : balance) {
  39.     if (it < 1) {
  40.       isFound = true;
  41.       break;
  42.     }
  43.   }
  44.   if (!isFound) {
  45.     for (auto& it : balance) {
  46.       it = it - 1;
  47.     }
  48.     return true;
  49.   }
  50.   return false;
  51. }
  52.  
  53. void fitExpression(vector<size_t>& balance, string& expression) {
  54.   if (fitBalance(balance)) {
  55.     expression = expression.substr(1, expression.size() - 2);
  56.     balance.pop_back();
  57.     balance.erase(balance.begin());
  58.   }
  59. }
  60.  
  61. bool hasOperator(const string& expression) {
  62.   for (size_t i = 0; i < kOperators.size(); i++) {
  63.     if (expression.find(kOperators[i]) != string::npos) {
  64.       return true;
  65.     }
  66.   }
  67.   return false;
  68. }
  69.  
  70. bool hasFirstFloorOperator(const string& expression,
  71.                            const vector<size_t>& balance) {
  72.   for (size_t i = 0; i < expression.size(); i++) {
  73.     if (balance[i] == 0) {
  74.       for (size_t j = 0; j < kOperators.size(); j++) {
  75.         if (expression[i] == kOperators[j]) {
  76.           return true;
  77.         }
  78.       }
  79.     }
  80.   }
  81.   return false;
  82. }
  83.  
  84. double calculate(string& expression, vector<size_t> balance) {
  85.   if (!hasOperator(expression)) {
  86.     return stod(expression);
  87.   }
  88.   while (!hasFirstFloorOperator(expression, balance)) {
  89.     fitExpression(balance, expression);
  90.   }
  91.   string left, right;
  92.   size_t operatorId = 0;
  93.   for (size_t i = 0; i < kOperators.size(); i++) {
  94.     if (expression.find(kOperators[i]) != string::npos) {
  95.       size_t operatorPos = 0;
  96.  
  97.       bool isFound = false;
  98.       for (size_t j = 0; j < kOperators.size() && !isFound; j++) {
  99.         for (size_t i = 0; i < expression.size() && !isFound; i++) {
  100.           if (balance[i] == 0) {
  101.             if (expression[i] == kOperators[j]) {
  102.               operatorPos = i;
  103.               operatorId = j;
  104.               isFound = true;
  105.             }
  106.           }
  107.         }
  108.       }
  109.  
  110.       left = expression.substr(0, operatorPos);
  111.       right =
  112.           expression.substr(operatorPos + 1, expression.size() - operatorPos);
  113.     }
  114.   }
  115.   switch (operatorId) {
  116.     case 0: {
  117.       return calculate(left, getBalanced(left)) +
  118.              calculate(right, getBalanced(right));
  119.     } break;
  120.     case 1: {
  121.       return calculate(left, getBalanced(left)) -
  122.              calculate(right, getBalanced(right));
  123.     } break;
  124.     case 2: {
  125.       return calculate(left, getBalanced(left)) *
  126.              calculate(right, getBalanced(right));
  127.     } break;
  128.     case 3: {
  129.       return calculate(left, getBalanced(left)) /
  130.              calculate(right, getBalanced(right));
  131.     } break;
  132.   }
  133. }
  134.  
  135. int main() {
  136.   vector<size_t> balance;
  137.   string expression;
  138.  
  139.   getline(cin, expression);
  140.   expression = getClean(expression);
  141.   balance = getBalanced(expression);
  142.  
  143.   fitExpression(balance, expression);
  144.   double value = calculate(expression, balance);
  145.   cout << value;
  146.  
  147.   return 0;
  148. }
  149.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement