Cod sursa(job #1623231)

Utilizator lflorin29Florin Laiu lflorin29 Data 1 martie 2016 18:11:30
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("bool.in");
ofstream fout("bool.out");

string aux, S, variabile;
int nr_variabile;

int prio[1234];
int val[1234];

stack<char>operatii;
vector<char>rezultat;

void makeOp() {
    prio['('] = prio[')'] = -22;

    prio['!'] = 4;
    prio['&'] = 3;
    prio['|'] = 2;

    val['f'] = 0;
    val['t'] = 1;
}


void adaug(char e, int &i) {
    string op;
    while(i < aux.size() && isupper(aux[i])) op += aux[i++];
    if(op == "NOT") S.push_back('!');
    else if(op == "AND") S.push_back('&');
    else if(op == "OR") S.push_back('|');
    else if(op == "TRUE") S.push_back('t');
    else if(op == "FALSE") S.push_back('f');
    else S.push_back(e);
    --i;
}

void fa_string_bun() {
    for(int i = 0; i < aux.size() ; ++i) {
        char e = aux[i];
        if(e == ' ') continue;
        else if(e == '(' || e == ')') S.push_back(e);
        else adaug(e, i);
    }

  //  for(auto e:S)
      //  cout<<e;
}

void fa_curr_op(int &i) {
    char ch = S[i];
    if(operatii.empty()){
        operatii.push(ch);return;}
    if(ch=='!'&&operatii.top()==ch){
        operatii.push(ch);return;
    }

    while(!operatii.empty() && prio[ch] <= prio[operatii.top()])
         rezultat.push_back(operatii.top()), operatii.pop();

     operatii.push(ch);
}

void goleste() {
    while(!operatii.empty() && operatii.top() != '(')
            rezultat.push_back(operatii.top()), operatii.pop();
    operatii.pop();
}

void makePolish() {
    operatii = stack<char>(); rezultat.clear();

    for(int i=0; i < S.size(); ++i) {
        if(S[i] == '(') operatii.push('(');
        else if(S[i] == ')') goleste();
        else if(isupper(S[i]) || islower(S[i])) rezultat.push_back(S[i]), rezultat.push_back(',');
        else fa_curr_op(i);
    }

    while(!operatii.empty())
        rezultat.push_back(operatii.top()), operatii.pop();
    for(auto e:rezultat)
        cout<<e;
}

bool rez(bool a, bool b, char ch) {
    if(ch == '|') return a | b;
    else if(ch == '&') return a & b;
    assert(1 == -1);
    return 1;
}

void perform(stack<int>&numere, int &i, vector<char>&vec_aux) {assert(numere.size());
    if(vec_aux[i] == '!'){
        bool valoare = numere.top(); numere.pop();
        numere.push(!valoare);
        return;
    }

    int a = numere.top();
    numere.pop();
    int b = numere.top();
    numere.pop();
    numere.push(rez(a, b, vec_aux[i]));
}

bool eval() {
    auto vec_aux = rezultat;
    stack<int>numere;

    for(int i = 0; i < vec_aux.size(); ++i) {
        char ch = vec_aux[i];
        if(ch == ',') continue;
       else if(isupper(ch) || islower(ch)) numere.push(val[ch]);
       else perform(numere, i, vec_aux);
    }

assert(numere.size());
    return numere.top();
}

int main() {
    getline(fin, aux);
    fin >> nr_variabile >> variabile;

    fa_string_bun();
    makeOp();
    makePolish();

    for(int i=0; i < nr_variabile; ++i) {
        val[variabile[i]] ^= 1;
        fout << eval();
    }

    return 0;
}