Sanlover

Untitled

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