Cod sursa(job #370850)

Utilizator iuly2freemanVasiliev Iulian iuly2freeman Data 2 decembrie 2009 16:23:38
Problema Evaluarea unei expresii Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include <fstream>
#include <stack>
#include <vector>
#include <sstream>

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

std::vector<std::string> postfix;

template <typename T>
T stringTo(std::string s)
{
   std::istringstream i(s);

   T x;
   i >> x;

   return x;
}

bool precedence(char A, char B)
{
	if (A == '(') return false;
	if (B == '(') return false;
	if (B == ')') return true;
	if ((A == '*') || (A == '/')) return true;
	if ((B == '*') || (B == '/')) return false;

	return true;
}

bool isOperand(char ch)
{
	if  (((ch >= 'a') && (ch <= 'z')) || 
		((ch >= 'A')  && (ch <= 'Z')) ||
		((ch >= '0')  && (ch <= '9')))
			return false;
			
	else return true;
}

void convert(const std::string infix)
{
	std::stack<char> operatorStack;
	char symbol;
	std::string number = "";

	for (unsigned int i = 0; i < infix.size(); ++i)
	{
		symbol = infix[i];
		if (!isOperand(symbol))
		{
			number += symbol;
		}
		else
		{
			postfix.push_back(number);
			number = "";
			while ((!operatorStack.empty()) && (precedence(operatorStack.top(), symbol)))
			{
				number = operatorStack.top();
				operatorStack.pop();
				postfix.push_back(number);
				number = "";
			}
			if ((!operatorStack.empty()) && (symbol == ')')) operatorStack.pop();
			else operatorStack.push(symbol);
		}
	}

	while (!operatorStack.empty())
	{
		number = operatorStack.top();
		operatorStack.pop();
		postfix.push_back(number);
		number = "";
	}
}

long int solve()
{
	if (!isOperand(postfix.back()[0]))
	{
		long int x = stringTo<long int>(postfix.back());
		postfix.pop_back();
		return x;
	}
	else
	{
		long int a = 0, b = 0;
		char sign = stringTo<char>(postfix.back());
		postfix.pop_back();
		b = solve();
		a = solve();
		//std::cout << a << sign << b;
		switch (sign)
		{
			case '+' : return a + b;
			case '-' : return a - b;
			case '*' : return a * b;
			case '/' : return a / b;
		}	
	}
	return 1;
}

int main(void)
{
	std::string infix;
	
	fin >> infix;
	
	infix += "+";

	convert(infix);
	
	for (unsigned int i = 0; i < postfix.size(); ++i)
	{
			if (postfix[i] == "") postfix.erase(postfix.begin() + i);
	}
	
	postfix.pop_back();
	
	/*std::cout << std::endl;	
	copy(postfix.begin(), postfix.end(), std::ostream_iterator<std::string>(std::cout, " "));
	std::cout << std::endl;*/
	
	fout << solve();	

	return 0;
}