Sanlover

Untitled

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