Pagini recente » Cod sursa (job #432543) | Cod sursa (job #2689025) | Cod sursa (job #372263) | Cod sursa (job #302562) | Cod sursa (job #2471128)
#include <bits/stdc++.h>
#define L_MAX 1000
using namespace std;
//functie care returneaza TIPUL TEXTULUI care incepe cu pozitia "pos" in expresia "exp"
//și anume daca este operator, variabila, valoare de adevar, ... (in primul compartiment al perechii)
//precum și TEXTUL IN SINE (in al doilea compartiment al perechii)
pair<string, string> parser(string& exp, size_t pos)
{
if(exp[pos] == '(') return make_pair("paranteza deschisa", "(");
if(exp[pos] == ')') return make_pair("paranteza inchisa", ")");
if(exp[pos] == ' ') return make_pair("spatiu liber", " ");
if(exp[pos] == '\0') return make_pair("sfarsit", "\\0");
string value("");
while(exp[pos] != '(' && exp[pos] != ')' && exp[pos] != ' ' && exp[pos] != '\0')
{
value += exp[pos];
++pos;
}
if(value == "AND") return make_pair("operator", value);
if(value == "NOT") return make_pair("operator", value);
if(value == "OR") return make_pair("operator", value);
if(value == "TRUE") return make_pair("valoare de adevar", value);
if(value == "FALSE") return make_pair("valoare de adevar", value);
if(value >= "A" && value <= "Z") return make_pair("variabila", value);
return make_pair("-1", "-1");
}
//functie care returneaza pozitia unei majuscule in alfabet
//prima pozitie o consideram 0
inline size_t pozitie_litera(string& x)
{
return x[0] - 'A';
}
//functie care returneaza prioritatea unui operator
//valorile sunt doar o conventie
size_t prioritate_operator(string& op)
{
if(op == "NOT") return 3;
if(op == "AND") return 2;
if(op == "OR") return 1;
return 0; //pentru paranteza
}
//functie care evalueaza cea mai simpla expresie formata din doi operanzi si un operator
//B are o valoare implicita ca sa evitam precizarea lui in cazul operatorului NOT
size_t evalueaza_expresize_de_baza(string& op, bool A, bool B = false)
{
if(op == "AND") return A & B;
if(op == "OR") return A | B;
return !A;
}
//functie care evalueaza o expresie care contine variabile
//evaluarea este identica cu a evaluarii unei expresii in forma invers poloneza
//dar nu o mai tranformam intr-o expresie invers poloneza ci o evaluam direct
bool evalueaza_expresie(string& expresie, vector<bool> valoareVariabila)
{
vector<bool> stivaOperanzi;
//nu il declar "stack" deoarece trebuie sa accesez și alte elemente expceptand varful
stack<string> stivaOperatori;
pair<string, string> text_curent;
size_t i = 0;
do{
text_curent = parser(expresie, i);
//extragem textul curent
if(text_curent.first == "variabila")
{
stivaOperanzi.push_back(valoareVariabila[pozitie_litera(text_curent.second)]);
}
if(text_curent.first == "valoare de adevar")
{
if(text_curent.second == "TRUE" ) stivaOperanzi.push_back(true);
else stivaOperanzi.push_back(false);
}
if(text_curent.first == "paranteza deschisa")
{
stivaOperatori.push(text_curent.second);
}
if(text_curent.first == "operator" || text_curent.first == "paranteza inchisa")
{
while(!stivaOperatori.empty() && stivaOperatori.top() != "(" && prioritate_operator(text_curent.second) <= prioritate_operator(stivaOperatori.top()))
{
if(stivaOperatori.top() == "NOT")
{
stivaOperanzi[stivaOperanzi.size() - 1] = evalueaza_expresize_de_baza(stivaOperatori.top(), stivaOperanzi[stivaOperanzi.size() - 1]);
}
else
{
stivaOperanzi[stivaOperanzi.size() - 2] = evalueaza_expresize_de_baza(stivaOperatori.top(), stivaOperanzi[stivaOperanzi.size() - 2], stivaOperanzi[stivaOperanzi.size() - 1]);
stivaOperanzi.pop_back();
}
stivaOperatori.pop();
}
if(text_curent.first == "paranteza inchisa") stivaOperatori.pop(); //eliminam paranteza deschisa
else stivaOperatori.push(text_curent.second);
}
i = i + text_curent.second.size();
//schimbam pozitia sarind peste textul curent
} while(text_curent.first != "sfarsit");
//golim operatorii ramasi in stiva
while(!stivaOperatori.empty())
{
if(stivaOperatori.top() == "NOT")
{
stivaOperanzi[stivaOperanzi.size() - 1] = evalueaza_expresize_de_baza(stivaOperatori.top(), stivaOperanzi[stivaOperanzi.size() - 1]);
}
else
{
stivaOperanzi[stivaOperanzi.size() - 2] = evalueaza_expresize_de_baza(stivaOperatori.top(), stivaOperanzi[stivaOperanzi.size() - 2], stivaOperanzi[stivaOperanzi.size() - 1]);
stivaOperanzi.pop_back();
}
stivaOperatori.pop();
}
//raspunsul cautat se va afla in ultimul operand ramas
return stivaOperanzi[0];
}
int main()
{
ifstream fin("bool.in");
ofstream fout("bool.out");
string expresie;
//sir de caractere in care memoram expresia
getline(fin, expresie);
vector<bool> valoareVariabila(26) ;
//vector in care stocam valorile variabilelor problemei
for(size_t i = 0; i < 26; ++i) valoareVariabila[i] = false;
//din enunt, la inceput toate variabilele au valoarea false
size_t N;
//N-ul cu semnificatia din problema
fin >> N;
string c(" ");
//variabila in care stocam, pe rand, cate un caracter de pe ultima linie
//o folosim pentru a determina valoarea carei variabile se comuta
//nu folosim char din cauza faptului ca toate functiile iau ca parametii string-uri
//si programul e deja prea mare pentru funtion overload
for(size_t i = 1; i <= N; ++i)
{
fin >> c[0];
valoareVariabila[pozitie_litera(c)] = !valoareVariabila[pozitie_litera(c)];
//comutam valoarea unei variabile
fout << evalueaza_expresie(expresie, valoareVariabila);
//evaluam expresia și afișam rezultatul in fișier
}
return 0;
}