Cod sursa(job #841467)

Utilizator Brz_VladBrezae Vlad Brz_Vlad Data 24 decembrie 2012 12:00:24
Problema Evaluarea unei expresii Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.92 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXN 100000

// STACK ///////////////////////////////

typedef struct tagNode
{
	int value;
	struct tagNode *next;
}Node;

typedef struct tagStack
{
	Node* start;
}Stack;

void initStack(Stack *stack)
{
	stack->start = NULL;
}

void pushStack(Stack *stack, int value)
{
    Node *new = malloc(sizeof(Node));
    new->next = stack->start;
    new->value = value;
    stack->start = new;	
}

int topStack(Stack *stack)
{
	return stack->start->value;
}

void popStack(Stack *stack)
{
	Node* toDelete = stack->start;
	stack->start = stack->start->next;
	free(toDelete);
}

int isEmptyStack(Stack *stack)
{
	return stack->start == NULL;
}

void printStack(Stack *stack, int character)
{
	Node* q = stack->start;
	while( q != NULL ){
		if( character )
			printf("%c ", q->value);
		else
			printf("%d ", q->value);
		q = q->next;
	}
	printf("\n");
}

////////////////////////////////////////

char expresie[MAXN];
int n;

enum Type{VALUE,OPERATOR,PARENTHESIS};
Stack valori,operatori;

int calc(int val1, int val2, int op)
{
	switch(op){
		case '+': return val1 + val2;
		case '-': return val1 - val2;
		case '*': return val1 * val2;
		case '/': return val1 / val2;		
	}
}

int prioritate(int op)
{
	switch(op){
		case '+':
		case '-':
				return 1;
		case '*':
		case '/':
				return 2;
		case '(':
		case ')':
				return 3;
	}
}

void EvalFromStack(int prmin)
{
	int val1,val2;
	while( !isEmptyStack(&operatori) && topStack(&operatori) != '(' && prioritate( topStack(&operatori) ) >= prmin ){
		val2 = topStack(&valori);
		popStack(&valori);
		val1 = topStack(&valori);
		popStack(&valori);
		
		int op = topStack(&operatori);
		popStack(&operatori);
		int rezultat = calc(val1,val2, op);
		
		pushStack(&valori,rezultat);
	}	

	if( prmin == 0 ){
		popStack(&operatori); // pop (
	}
}

char* ReadNext(char* p,int* value,enum Type* type)
{
	if(	isdigit(*p) ){
		*type = VALUE;
		int val = 0;
		while( isdigit(*p) ){
			val = val*10 + *p - '0';
			p++;
		}
		*value = val;
		return p;		
	}
	else{
		*value = *p;
		if( *value == '(' || *value == ')' )
			*type = PARENTHESIS;
		else
			*type = OPERATOR;
		return p+1;
	}
}

int main(int argc, char* argv[])
{
	FILE *fin,*fout;
	fin = fopen("evaluare.in","r");
	fgets(expresie,MAXN,fin);
	expresie[strlen(expresie)-1] = 0;
	fclose(fin);
	
	initStack(&valori);
	initStack(&operatori);
	
	int value;
	enum Type type;
	char *p = expresie;
	while( *p != 0 ){
		p = ReadNext(p,&value,&type);
		
		switch(type){
			case VALUE:
				pushStack(&valori, value);
				break;
			case OPERATOR:
				EvalFromStack(prioritate(value));
				pushStack(&operatori, value);
				break;
			case PARENTHESIS:
				if( value == ')' )
					EvalFromStack(0);
				else
					pushStack(&operatori,value);
				break;			
		}
	}
	
	EvalFromStack(prioritate('+'));
	int result = topStack(&valori);
	
	fout = fopen("evaluare.out","w");
	fprintf(fout,"%d",result);
	fclose(fout);
	
	return 0;
}