Cod sursa(job #2675391)

Utilizator cristi_macoveiMacovei Cristian cristi_macovei Data 21 noiembrie 2020 16:07:19
Problema Evaluarea unei expresii Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4 kb
//#include <iostream>
//#include <fstream>
//#include <string>
//#include <cctype>
//
//std::string sir;
//int pos;
//
//void read() {
//  std::ifstream in("evaluare.in");
//
//  in >> sir;
//
//  in.close();
//}
//
//int expresie();
//int termen();
//int factor();
//
//int expresie() {
//  int val = termen();
//
//  while (pos < sir.size()) {
//    if (sir[pos] == '+') {
//      ++pos;
//      val += termen();
//    } else if (sir[pos] == '-') {
//      ++pos;
//      val -= termen();
//    } else {
//      break;
//    }
//  }
//
//  return val;
//}
//
//int termen() {
//  int val = factor();
//
//  while (pos < sir.size()) {
//    if (sir[pos] == '*') {
//      ++pos;
//      val *= factor();
//    } else if (sir[pos] == '/') {
//      ++pos;
//      val /= factor();
//    } else {
//      break;
//    }
//  }
//
//  return val;
//}
//
//int factor() {
//  int val = 0;
//
//  if (sir[pos] == '(') {
//    ++pos;
//    val = expresie();
//    ++pos;
//  } else {
//    while (isdigit(sir[pos])) {
//      val = 10 * val + (sir[pos] - '0');
//      ++pos;
//    }
//  }
//
//  return val;
//}
//
//int main() {
//  read();
//
//  std::ofstream out("evaluare.out");
//  out << expresie();
//
//  return 0;
//}

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

std::string expr;

int pos = 0;

bool issign(char c) {
  return c == '+' || c == '-' || c == '*' || c == '/';
}

int eval() {
//  std::cout << "recursive call starts from pos = " << pos << '\n';
  std::vector<int> stack;

  std::string number;

  char prev_sign = '+';
  int value;

  if (expr[pos] == '-') {
    ++pos;
    prev_sign = '-';
  }

  for (; pos < expr.size(); ++pos) {
//    std::cout << "currently at pos " << pos << ", char : " << expr[pos] << '\n';
    if (isdigit(expr[pos])) {
      number += expr[pos];
//      std::cout << "added " << expr[pos] << " to number string\n";
    } else if (issign(expr[pos])) {
//      std::cout << "sign found : " << expr[pos] << '\n';
      if (!number.empty())
        value = std::stoi(number);

      number.clear();

      if (prev_sign == '*') {
//        std::cout << "updated stack.back() from " << stack.back();
        stack.back() *= value;
//        std::cout << " to " << stack.back() << '\n';
      } else if (prev_sign == '/') {
//        std::cout << "updated stack.back() from " << stack.back();
        stack.back() /= value;
//        std::cout << " to " << stack.back() << '\n';
      } else if (prev_sign == '+') {
        stack.push_back(value);
//        std::cout << "added " << stack.back() << '\n';
      } else if (prev_sign == '-') {
        stack.push_back(-value);
//        std::cout << "added " << stack.back() << '\n';
      }

      prev_sign = expr[pos];
    } else if (expr[pos] == '(') {
//      std::cout << "start bracket found\n";
      ++pos;
      value = eval();
//      std::cout << "bracket evaluated, value = " << value << '\n';
    } else if (expr[pos] == ')') {
//      std::cout << "end bracket found\n";

      if (!number.empty())
        value = std::stoi(number);
      number.clear();

      if (prev_sign == '*') {
//        std::cout << "updated stack.back() from " << stack.back();
        stack.back() *= value;
//        std::cout << " to " << stack.back() << '\n';
      } else if (prev_sign == '/') {
//        std::cout << "updated stack.back() from " << stack.back();
        stack.back() /= value;
//        std::cout << " to " << stack.back() << '\n';
      } else if (prev_sign == '+') {
        stack.push_back(value);
//        std::cout << "added " << stack.back() << '\n';
      } else if (prev_sign == '-') {
        stack.push_back(-value);
//        std::cout << "added " << stack.back() << '\n';
      }

      break;
    }
  }

  int ans = 0;
  for (int el : stack)
    ans += el;

//  std::cout << "returns " << ans << '\n';
  return ans;
}

void read() {
  std::ifstream in("evaluare.in");

  std::getline(in, expr);
  expr += '+';

  in.close();
}

int main() {
  read();

  std::ofstream out("evaluare.out");
  out << eval() << '\n';

  out.close();
  return 0;
}