Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- static const string kOperators = "+-*/";
- string getClean(string str) {
- for (string::iterator it = str.begin(); it != str.end(); ++it) {
- while (*it == ' ') {
- it = str.erase(it);
- }
- }
- return str;
- }
- vector<size_t> getBalanced(const string& expression) {
- vector<size_t> result(expression.size());
- size_t layerId = 0;
- for (size_t i = 0; i < expression.size(); i++) {
- if (expression[i] == '(') {
- layerId++;
- result[i] = layerId;
- } else if (expression[i] == ')') {
- result[i] = layerId;
- layerId--;
- } else {
- result[i] = layerId;
- }
- }
- return result;
- }
- bool fitBalance(vector<size_t>& balance) {
- bool isFound = false;
- for (auto& it : balance) {
- if (it < 1) {
- isFound = true;
- break;
- }
- }
- if (!isFound) {
- for (auto& it : balance) {
- it = it - 1;
- }
- return true;
- }
- return false;
- }
- void fitExpression(vector<size_t>& balance, string& expression) {
- if (fitBalance(balance)) {
- expression = expression.substr(1, expression.size() - 2);
- balance.pop_back();
- balance.erase(balance.begin());
- }
- }
- bool hasOperator(const string& expression) {
- for (size_t i = 0; i < kOperators.size(); i++) {
- if (expression.find(kOperators[i]) != string::npos) {
- return true;
- }
- }
- return false;
- }
- bool hasFirstFloorOperator(const string& expression,
- const vector<size_t>& balance) {
- for (size_t i = 0; i < expression.size(); i++) {
- if (balance[i] == 0) {
- for (size_t j = 0; j < kOperators.size(); j++) {
- if (expression[i] == kOperators[j]) {
- return true;
- }
- }
- }
- }
- return false;
- }
- double calculate(string& expression, vector<size_t> balance) {
- if (!hasOperator(expression)) {
- return stod(expression);
- }
- while (!hasFirstFloorOperator(expression, balance)) {
- fitExpression(balance, expression);
- }
- string left, right;
- size_t operatorId = 0;
- for (size_t i = 0; i < kOperators.size(); i++) {
- if (expression.find(kOperators[i]) != string::npos) {
- size_t operatorPos = 0;
- bool isFound = false;
- for (size_t j = 0; j < kOperators.size() && !isFound; j++) {
- for (size_t i = 0; i < expression.size() && !isFound; i++) {
- if (balance[i] == 0) {
- if (expression[i] == kOperators[j]) {
- operatorPos = i;
- operatorId = j;
- isFound = true;
- }
- }
- }
- }
- left = expression.substr(0, operatorPos);
- right =
- expression.substr(operatorPos + 1, expression.size() - operatorPos);
- }
- }
- switch (operatorId) {
- case 0: {
- return calculate(left, getBalanced(left)) +
- calculate(right, getBalanced(right));
- } break;
- case 1: {
- return calculate(left, getBalanced(left)) -
- calculate(right, getBalanced(right));
- } break;
- case 2: {
- return calculate(left, getBalanced(left)) *
- calculate(right, getBalanced(right));
- } break;
- case 3: {
- return calculate(left, getBalanced(left)) /
- calculate(right, getBalanced(right));
- } break;
- }
- }
- int main() {
- vector<size_t> balance;
- string expression;
- getline(cin, expression);
- expression = getClean(expression);
- balance = getBalanced(expression);
- fitExpression(balance, expression);
- double value = calculate(expression, balance);
- cout << value;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement