Cod sursa(job #2041812)

Utilizator Spiromanii_MessiUNIBUCThrowTerror Spiromanii_Messi Data 17 octombrie 2017 19:39:23
Problema Evaluarea unei expresii Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 3.76 kb
#include <bits/stdc++.h>

using namespace std ;

ifstream fin ("evaluare.in") ;
ofstream fout ("evaluare.out") ;

const int MAX = 1e5 + 14 ;

int stackk [MAX] ; 
int st ; 

bool isOperator (char c) {
	return c == '+' or c == '-' or c == '*' or c == '/' or c == '(' or c == ')' ;
}

int lim = -(2e9) ; 

map <int, char> whichOperator ; 

int convert (string &s) {
	if (s == "+") {
		return lim ; 
	}
	else if (s == "-") return lim - 1 ; 
	else if (s == "*") return lim - 2 ;
	else if (s == "/") return lim - 3 ; 
	else if (s == "(") return lim - 4 ; 
	else if (s == ")") return lim - 5 ; 
	else {
		int nr = 0 ; 
		for (auto &x : s) {
			nr = nr * 10 + x - '0' ; 
		}
		return nr ;
	}
}

int solve (int a, int b, int c) {
	assert (a > lim) ;
	assert (c > lim) ;  
	if (whichOperator [b] == '+') {
		return a + c ; 
	}
	else if (whichOperator [b] == '-') {
		return a - c ; 
	}
	else if (whichOperator [b] == '*') {
		return a * c ; 
	}
	else if (whichOperator [b] == '/') {
		return a / c ; 
	}
	// cout << whichOperator [b] << "problem\n" ; 
	assert (0) ; 
}

int main(int argc, char const *argv[])
{
	whichOperator [lim] = '+' ; 
	whichOperator [lim - 1] = '-' ;  
	whichOperator [lim - 2] = '*' ;  
	whichOperator [lim - 3] = '/' ;  
	whichOperator [lim - 4] = '(' ;  
	whichOperator [lim - 5] = ')' ;  
	vector <string> separated ;
	string s ; 
	string prev = "" ; 
	fin >> s ; 
	for (auto &elem : s) {
		if (elem == ' ') continue ; 
		if (isOperator (elem)) {
			if (prev != "") {
				separated.push_back (prev) ; 
			}
			prev = "" ;
			prev += elem ;
			separated.push_back (prev) ; 
			prev = "" ; 
		}
		else {
			prev += elem ; 
		}
	}
	if (prev != "") {
		separated.push_back (prev) ; 
	}
/*	for (auto &x : separated) {
		cout << x << '\n' ; 
	}
	return 0 ; */
	for (auto &x : separated) {
		int convertedValue = convert (x) ; 
		if (whichOperator.find (convertedValue) == whichOperator.end()) {
			++ st ;
			stackk [st] = convertedValue ; 
		}
		else if (whichOperator [convertedValue] == '+' or whichOperator [convertedValue] == '-') {
			if (st - 1 >= 1 and whichOperator [stackk [st - 1]] != '(') {
				assert (whichOperator [stackk[st - 1]]) ;
				auto solver = solve (stackk [st - 2], stackk [st - 1], stackk [st]) ; 
				// cout << whichOperator [stackk[st - 1]] << '\n' ; 
				// cout << solver << '\n' ; 
				// cout << st << '\n' ; 
				
				st = st - 2 ;
				stackk [st] = solver ;
				++ st ;
				stackk [st] = convertedValue ; 
			}
			else {
				++ st ;
				stackk [st] = convertedValue ;	
			}
		}
		else if (whichOperator [convertedValue] == '*' or whichOperator [convertedValue] == '/') {
			if (st - 1 >= 1 and whichOperator [stackk [st - 1]] != '(' and whichOperator [stackk [st - 1]] != '+' and whichOperator [stackk [st - 1]] != '-') {
				assert (whichOperator [stackk[st - 1]]) ;
				auto solver = solve (stackk [st - 2], stackk [st - 1], stackk [st]) ; 
				// cout << solver << '\n' ; 
				st = st - 2 ;
				stackk [st] = solver ;
				++ st ;
				stackk [st] = convertedValue ; 
			}
			else {
				++ st ;
				stackk [st] = convertedValue ;	
			}
		}
		else if (whichOperator [convertedValue] == ')') {
			while (st - 1 >= 1 and whichOperator [stackk [st - 1]] != '(') {
				auto solver = solve (stackk [st - 2], stackk [st - 1], stackk [st]) ; 
				// cout << stackk [st - 2] << ' ' << stackk [st - 1] << ' ' << stackk [st] << '\n' ; 
				// cout << solver << '\n' ; 
				st = st - 2 ;
				stackk [st] = solver ;
			}
			auto keep = stackk [st] ; 
			// cout << "keep is " << keep << '\n' ; 
			-- st ; 
			stackk [st] = keep ;
		}
		else {
			assert (whichOperator [convertedValue] == '(') ;
			++ st ; 
			stackk [st] = convertedValue ; 
		}
	}
	while (st > 1) {
		auto solver = solve (stackk [st - 2], stackk [st - 1], stackk [st]) ;
		st = st - 2 ; 
		stackk [st] = solver ; 
	}
	fout << stackk [1] ; 
	return 0;
}