Cod sursa(job #492580)

Utilizator dcm9000Dinu Cristian Mircea - UPB dcm9000 Data 15 octombrie 2010 01:10:08
Problema Bool Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#define FILE_IN "bool.in"
#define FILE_OUT "bool.out"

int N;
char EXPR[1001];
char VARS[26];

typedef struct
{
	char op;
	void* stanga;
	void* dreapta;
} Nod;

Nod NODURI[1000];
int NR_NODURI = 0;

Nod* parseExpr(char** expr);
Nod* parseTermen(char** expr);
Nod* parseFactor(char** expr);

void lexare(char* expr)
{
	char* ptr = expr;

	while (1)
	{
		char c = *(expr++);

		if (c == ' ') continue;
		if (!strncmp(expr-1, "FALSE", 5)) { *(ptr++)='0'; expr += 4; continue; }
		if (!strncmp(expr-1, "TRUE", 4)) { *(ptr++)='1'; expr += 3; continue; }
		if (!strncmp(expr-1, "NOT", 3)) { *(ptr++)='!'; expr += 2; continue; }
		if (!strncmp(expr-1, "AND", 3)) { *(ptr++)='&'; expr += 2; continue; }
		if (!strncmp(expr-1, "OR", 2)) { *(ptr++)='|'; expr++; continue; }

		*(ptr++) = c;
		if (!c) break;
	}
}

Nod* parseExpr(char** expr)
{
	char* ptr = *expr;
	Nod* n1 = parseTermen(&ptr);

	while (*ptr == '|')
	{
		ptr++;
		Nod* nn = NODURI+(NR_NODURI++);
		nn->op = '|';
		nn->stanga = n1;
		nn->dreapta = parseTermen(&ptr);
		n1 = nn;
	}

	*expr = ptr;

	return n1;
}

Nod* parseTermen(char** expr)
{
	char* ptr = *expr;
	Nod* n1 = parseFactor(&ptr);

	while (*ptr == '&')
	{
		ptr++;
		Nod* nn = NODURI+(NR_NODURI++);
		nn->op = '&';
		nn->stanga = n1;
		nn->dreapta = parseFactor(&ptr);
		n1 = nn;
	}

	*expr = ptr;

	return n1;
}

Nod* parseFactor(char** expr)
{
	char* ptr = *expr;

	Nod* n1;

	int negate = 0;
	if (*ptr == '!') { negate = 1; ptr++; }

	if (*ptr == '(')
	{
		ptr++;
		n1 = parseExpr(&ptr);
		ptr++;
	}
	else
	{
		n1 = NODURI+(NR_NODURI++);
		n1->op = *(ptr++);
	}

	if (negate)
	{
		Nod* nn = NODURI+(NR_NODURI++);
		nn->op = '!';
		nn->stanga = n1;
		n1 = nn;
	}

	*expr = ptr;

	return n1;
}

int eval(Nod* nod)
{
	switch (nod->op)
	{
		case '0': return 0;
		case '1': return 1;
		case '&': return eval((Nod*)nod->stanga) && eval((Nod*)nod->dreapta);
		case '|': return eval((Nod*)nod->stanga) || eval((Nod*)nod->dreapta);
		case '!': return !eval((Nod*)nod->stanga);
		default: return VARS[nod->op - 'A'];
	}
}

int main()
{
	ifstream fisIn(FILE_IN);
	ofstream fisOut(FILE_OUT);

	fisIn.getline(EXPR, 1001);
	fisIn >> N;
	fisIn.ignore(2,'\n');

	lexare(EXPR);

	char* ptr = EXPR;
	Nod* expr = parseExpr(&ptr);

	memset(VARS, 0, 26);
	
	for (int i=0; i<N; i++)
	{
		char c;
		fisIn >> c;

		VARS[c-'A'] ^= 1;

		fisOut << eval(expr);
	}
}