Cod sursa(job #898172)

Utilizator cprogrammer1994Cprogrammer cprogrammer1994 Data 28 februarie 2013 08:30:05
Problema Evaluarea unei expresii Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <cstring>
#include <cstdio>
#include <cmath>

int size;
char str[100007];

struct Unit {
	int val;
	int wgt;
	char oper;
	Unit * next;
	Unit(char o, int w, int v) {
		next = 0;
		oper = o;
		wgt = w;
		val = v;
	}
};

Unit * first;
Unit ** last = &first;

void regist(char oper, int wgt, int val) {
	(*last) = new Unit(oper, wgt, val);
	last = &(*last)->next;
}

int main() {
	FILE * in = fopen("evaluare.in", "rt");
	FILE * out = fopen("evaluare.out", "wt");

	fgets(str, 100007, in);
	size = strlen(str);

	int wgt = 0;
	int val = 0;
	regist('+', 0, 0);
	regist('+', 0, 0);
	for (int i = 0; i < size; ++i) {
		if (str[i] == '(') {
			wgt += 2;
		}
		if ('0' <= str[i] && str[i] <= '9') {
			val = val * 10 + str[i] - '0';
		}
		if (str[i] == '+' || str[i] == '-') {
			regist(str[i], wgt + 0, val);
			val = 0;
		}
		if (str[i] == '*' || str[i] == '/') {
			regist(str[i], wgt + 1, val);
			val = 0;
		}
		if (str[i] == ')') {
			wgt -= 2;
		}
	}
	regist(0, 0, val);

	Unit * a;
	Unit * b;
	Unit * c;

	a = first;
	b = a ? a->next : 0;
	c = b ? b->next : 0;
	while (c) {
		while (c) {
			if (a->wgt <= b->wgt && b->wgt >= c->wgt) {
				switch (b->oper) {
					case '+': b->val += c->val; break;
					case '-': b->val -= c->val; break;
					case '*': b->val *= c->val; break;
					case '/': b->val /= c->val; break;
				}
				b->oper = c->oper;
				b->wgt = c->wgt;

				b->next = c->next;
				c = c->next;
			} else {
				a = a->next;
				b = b->next;
				c = c->next;
			}
		}
		a = first;
		b = a ? a->next : 0;
		c = b ? b->next : 0;
	}

	fprintf(out, "%d", first->next->val);

	fclose(in);
	fclose(out);
}