Cod sursa(job #640271)

Utilizator the_snyper06FMI - ALexandru Mihai the_snyper06 Data 25 noiembrie 2011 04:02:16
Problema Evaluarea unei expresii Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.75 kb
#include<cstdio>
#include<string.h>
#include<algorithm>

using namespace std;
int n;
char exp[100005], exp2[100005];

int Eval(int a, char op, int b);
void EvalParanteza(int start);
void Replace(int start, int stop, int x);
void Insert(int poz, char op);
void SelectOperatiePrioritara();
void Calc();

int main() {
	int i;
	
	freopen("evaluare.in", "r", stdin), freopen("evaluare.out", "w", stdout);
	exp[0] = '#', scanf("%s", exp + 1);
	n = strlen(exp);
	
	EvalParanteza(n);
	SelectOperatiePrioritara();
	//printf("\n--------\n%s\n----------\n", exp);
	EvalParanteza(n);
	
	Calc();
	
	return 0;
}

int Eval(int a, char op, int b) {
	switch (op) {
		case '+': return a + b;
		case '-': return a - b;
		case '*': return a * b;
		case '/': return a / b;
	}
	return a;
}

void Insert(int poz, char op) {
	strncpy(exp2, exp, poz);
	exp2[poz + 1] = op;
	strcpy(exp2 + poz + 2, exp + poz + 1);
	strcpy(exp, exp2);
	n = strlen(exp);
}

void SelectOperatiePrioritara() {
	int i;
	
	for(i = 1; i <= n; i++)
		if(exp[i] == '*' || exp[i] == '/') {
			int k = i - 1;
			while ('0' <= exp[k] && exp[k] <= '9') k--;
			Insert(k, '(');
			i++;
			k = i + 1;
			while ('0' <= exp[k] && exp[k] <= '9') k++;
			Insert(k - 1, ')');
		}
}

void EvalParanteza(int start) {
	int i = start, a, b;
	char op;
	
	while(i > 0) {
		while (exp[i] != '(' && i > 0) i--;
		if(i != 0) {
			start = i, i++; // pozitionare inainte de paranteza

			//printf("{exp = %s,; start = %d; i = %d; exp[i] = %c; exp[start] = %c;}\n", exp, start, i, exp[i], exp[start]);

			a = b = 0;
			op = '#';
			while ('0' <= exp[i] && exp[i] <= '9') a = a * 10 + (exp[i++] - '0');
			op = exp[i], i++;
			while ('0' <= exp[i] && exp[i] <= '9') b = b * 10 + (exp[i++] - '0');
			i++; // pozitionare dupa paranteza

			//printf("> %d %c %d >\n", a, op, b);
		
			Replace(start, i, Eval(a, op, b));
			//printf("%s\n", exp);
		}
	}
}

void Replace(int start, int stop, int x) {
	int i = 0, x0 = 0;
	char c[11];
	
	while (x > 0) x0 = x0 * 10 + x % 10 , x /= 10;
	while (x0 > 0) c[i++] = x0 % 10 + '0', x0 /= 10;
	c[i] = '\0';
	
	strncpy(exp2, exp, start); // copiez din exp pana la start
	strcpy(exp2 + start, c); // copiex rezultatul
	strcpy(exp2 + start + i, exp + stop); // copiez din exp incepand cu stop
	strcpy(exp, exp2);
	n = strlen(exp);
}

void Calc() {
	int i = 1, s = 0, a = 0;
	char op = '#';
	
	while (i <= n) {
		a = 0;
		op = '#';
		
		while ('0' <= exp[i] && exp[i] <= '9') a = a * 10 + (exp[i++] - '0');
		op = exp[i++];
		s = Eval(s, op, a);
		//printf("{s = %d; op = %c; a = %d; }\n", s, op, a);
	}
	
	i = n - 1;
	while ('0' <= exp[i] && exp[i] <= '9') i--;
	op = exp[i++];
	i++;
	while ('0' <= exp[i] && exp[i] <= '9') a = a * 10 + (exp[i++] - '0');
	//printf("{s = %d; op = %c; a = %d; }\n", s, op, a);
	
	s = Eval(s, op, a);	
	printf("%d\n", s);
}