Cod sursa(job #1332151)

Utilizator charmpitzAndrei Pit charmpitz Data 1 februarie 2015 19:07:56
Problema Evaluarea unei expresii Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb

/*
Enunt:
Evaluarea unei expresii
Se da un sir de caractere ce reprezinta o expresie aritmetica.

Cerinta
Afisati rezultatul obtinut prin evaluarea expresiei.

Date de intrare
Fisierul de intrare evaluare.in va contine pe prima linie un sir de caractere compus din cifre ( '0' - '9' ), operatorii '+', '-', '*', '/' si paranteze( '(', ')' ).

Date de iesire
In fisierul de iesire evaluare.out se va scrie un singur numar intreg care reprezinta valoarea obtinuta in urma evaluarii expresiei.

Restrictii si precizari
1 ≤ lungimea sirului ≤ 100 000
Operatorii '+','-','*' au semnificatia cunoscuta de la matematica, iar operatorul '/' reprezinta catul impartirii intregi a doua numere
Ordinea efectuarii operatiilor este cea normala
Se garanteaza ca rezultatul final, operanzii si orice rezultat intermediar nu depasesc in modul 1 000 000 000 (un miliard)
Exemplu
evaluare.in	
(1+1)*13+10/2

evaluare.out
31
*/

/*
Rezolvare:

*/


#include <stdio.h>
#include <string.h>
#include <ctype.h>

FILE *in, *out;
int n, result;
char x[200010];

int expresie (int p1, int p2) {
	int i, c, pos, nr_left, nr_right, nr, semn;

	while (x[p1] == '(')
	{
		c = 0;
		for (i=p1; i<=p2; i++)
		{
			if (x[i] == '(')
				c++;

			if ((x[i] == ')') && (c == 1))
				break;
		}

		if (i == p2)
		{
			p1++;
			p2--;
		}
		else
		{
			break;
		}
	}

	pos = p1;
	c = 1;
	for (i=p1; i<=p2; i++)
	{
		switch(x[i]) {
			case '(':
				c++;
				break;

			case ')':
				c--;

				break;

			case '+':
				if ((c == 1) && (i > p1) && ((isdigit(x[i-1])) || (x[i-1] == ')')))
				{
					pos = i;
				}
				break;

			case '-':
				if ((c == 1) && (i > p1) && ((isdigit(x[i-1])) || (x[i-1] == ')')))
				{
					pos = i;
				}
				break;

			case '*':
				if ((c == 1) && ((pos == p1) || (x[pos] == '*') || (x[pos] == '/')))
				{
					pos = i;
				}
				break;

			case '/':
				if ((c == 1) && ((pos == p1) || (x[pos] == '*') || (x[pos] == '/')))
				{
					pos = i;
				}
				break;
		}
	}

	if (pos == p1)
	{
		if (x[p1] == '+')
		{
			return expresie(p1+1, p2);
		}
		else
		{
			if (x[p1] == '-')
			{
				return -expresie(p1+1, p2);
			}
			else
			{
				nr = 0;
				for (i=p1; i<=p2; i++)
				{
					nr = nr * 10 + (x[i] - 48);
				}

				return nr;
			}
		}
	}
	else
	{
		nr_left = expresie(p1, pos-1);
		nr_right = expresie(pos+1, p2);
		
		switch (x[pos]) 
		{
			case '+':
				return nr_left + nr_right;
				
			case '-':
				return nr_left - nr_right;

			case '*':
				return nr_left * nr_right;

			case '/':
				return nr_left / nr_right;
		}
	}
}

int main ()
{
	in = fopen("evaluare.in", "r");
	out = fopen("evaluare.out", "w");

	fscanf(in, "%s", &x[0]);

	n = strlen(x);

	result = expresie(0, n-1);
	
	fprintf(out, "%d\n", result);

	fclose(out);
	fclose(in);

	return 0;
}