Cod sursa(job #495705)

Utilizator marius21Marius Petcu marius21 Data 26 octombrie 2010 16:29:29
Problema Evaluarea unei expresii Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.2 kb
#include <cstdio>
#include <cstdlib>
#include <list>

using namespace std;

FILE *fin=fopen("evaluare.in","r");
FILE *fout=fopen("evaluare.out","w");

enum kOperands {
	kNull = 0,
	kRightPar,
	kPlus,
	kMinus,
	kMult,
	kDiv,
	kLeftPar
};

enum kTypes {
	kTypeOperand = 0,
	kTypeOperator
};

struct el
{
	int type,value;
}; 
el a[100000];
int n = 0;

inline bool iscifra(char c)
{
	return (c>='0')&&(c<='9');
}

inline int opFromChar(char c)
{
	switch (c)
	{
		case '(':
			return kLeftPar;
		case ')':
			return kRightPar;
		case '+':
			return kPlus;
		case '-':
			return kMinus;
		case '*':
			return kMult;
		case '/':
			return kDiv;
		default:
			return kNull;
	}
}

void process_operand(int nr)
{
    a[n].type=kTypeOperand;
	a[n].value = nr;
	n++;
}

list<int> stack;

void process_operator(int nr)
{
    int crr;
    while (!(stack.empty())&&((crr=stack.back())>=nr))
	{
		if (crr!=kLeftPar)
		{
			a[n].type=kTypeOperator;
			a[n].value=crr;
			n++;
		    stack.pop_back();
		} else {
            if (nr==kRightPar)
                stack.pop_back();
            break;
        }
	}
	if ((nr!=kRightPar)&&(nr!=kNull))
	{
		stack.push_back(nr);
	}
}

int solve(int a, int b, int op)
{
	switch(op)
	{
		case kPlus:
			return a+b;
		case kMinus:
			return a-b;
		case kMult:
			return a*b;
		case kDiv:
			return a/b;
		default:
			return 0; 
	}
}

int solve_polonese()
{
	for (int i=0; i<n ;i++)
	{
        if (a[i].type==kTypeOperand)
        {
			stack.push_back(a[i].value);
        }
		else
		{
			int ond2 = stack.back();
			stack.pop_back();
			int ond1 = stack.back();
			stack.pop_back();
            int res = solve(ond1,ond2,a[i].value);
			stack.push_back(res);
		}
	}
	return stack.back();
}

int main (int argc, char * const argv[]) {
    char c;
	int nr = 0;
	int hasnr = 0;
	while ((c=fgetc(fin))!=EOF)
	{
		if (c==' ') continue;
        if (c=='\n') continue;
        if (c=='\r') continue;
		if (iscifra(c))
		{
			hasnr = 1;
			nr=nr*10+c-'0';
		}
		else
		{
			if (hasnr)
				process_operand(nr);
			hasnr = 0;
            nr = 0;
			process_operator(opFromChar(c));
		}
	}
	if (hasnr)
		process_operand(nr);
	process_operator(kNull);
    fprintf(fout,"%d\n",solve_polonese());
    fclose(fin);
	fclose(fout);
    return 0;
}