Cod sursa(job #941739)

Utilizator andreiagAndrei Galusca andreiag Data 19 aprilie 2013 16:43:03
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.63 kb
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <set>
#include <stack>
#include <string>
#include <cctype>
#include <cstdio>

using namespace std;

stack<char> operations;
stack<bool> factors;
map<char, bool> dict;
// NOT > AND > OR;

int order(char c)
{
    int ret = 0;
    switch (c) {
        case '!': ret = 3; break;
        case '&': ret = 2; break;
        case '|': ret = 1; break;
    }
    return ret;
}

bool high_prec(char a, char b)
{
    int x = order(a);
    int y = order(b);
    return (x > y);
}

string process_line(string &line)
{
    string ret;
    operations.push('#');
    int s = line.size();
    int  i = 0;
    while (i < s) {
        char c = line[i];
        if (c == ' ') i++;
        else if (c == '(') {operations.push(c); i++;} //open parentheses
        else if (c == ')') {char d = operations.top();
                            while(d != '('){ret += d; operations.pop(); d = operations.top();}
                            operations.pop(); i++;} //close parentheses
        else if (isalpha(c) && (i == s-1 || !isalpha(line[i+1]))) {ret += c; i++;} //single letter, so symbol
        else if (c == 'T') {ret += '1'; i += 4;}
        else if (c == 'F') {ret += '0'; i += 5;}
        else if (c == 'N') {operations.push('!'); i += 3;}
        else {int k = 1; switch (c) {
                        case 'A' : {c = '&'; k = 3;} break;
                        case 'O' : {c = '|'; k = 2;} break;
                        //case 'N' : {c = '!'; k = 3;} break;
                        }
              char d = operations.top();
              if (d == '(' || d == '#') {operations.push(c); i += k;}
              else { while (d != '(' && d != '#' && !high_prec(c,d)) {
                                ret += d; operations.pop(); d = operations.top();
                            }
                    operations.push(c); i += k;
            }
        }
    }
    char d = operations.top();
    while(d != '#') {
        ret += d;
        operations.pop();
        d = operations.top();
    }
    return ret;
}

bool eval_str(string &RPN)
{
    bool tmp1, tmp2;
    int i = 0;
    int s = RPN.size();
    while(i < s) {
        char c = RPN[i];
        if(isalnum(c)) factors.push(dict[c]);
        else switch (c) {
                case '!':   tmp1 = factors.top(); factors.pop();
                            factors.push(!tmp1); break;
                case '&':   tmp1 = factors.top(); factors.pop();
                            tmp2 = factors.top(); factors.pop();
                            factors.push(tmp1 && tmp2); break;
                case '|':   tmp1 = factors.top(); factors.pop();
                            tmp2 = factors.top(); factors.pop();
                            factors.push(tmp1 || tmp2); break;
            }
        i++;
    }

    return factors.top();
}



int main()
{

    freopen("bool.in", "r", stdin);
    ofstream fout("bool.out");

    string line, change;
    int N;
    getline(cin, line);
    scanf("%d\n",&N);
    getline(cin, change);
    //cout << N << endl << change << endl;

    dict['0'] = 0;
    dict['1'] = 1;

    for(int i = 0; i < 26; i++)
        dict[i+65] = false;

    /*
    for(map<char, bool>::iterator it = dict.begin(); it != dict.end(); it++)
        cout << it->first << ":" << it->second << " "; */

    string RPN = process_line(line);
    //fout << RPN << endl;

    for(int i = 0; i < N; i++) {
        char c = change[i];
        dict[c] = !dict[c];
        bool tmp = eval_str(RPN);
        fout << tmp;
    }
    fout << endl;

    return 0;
}