Cod sursa(job #1825729)

Utilizator alexnekiNechifor Alexandru alexneki Data 9 decembrie 2016 16:46:46
Problema Bool Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.98 kb
#include <iostream>
#include <fstream>
#include <map>
#include <cassert>

using namespace std;

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

int const prmax = 3; //number of priority levels of the operators

int const nmax = 1001;
map<string, char> f;
map<char, int> prio;
map<char, bool> value;
char ex[2 * nmax - 1]; //expression to be evaluated
char postfix[2 * nmax - 1];
int n; //number of elements in clean infix expression
int npost; //number of elements in postfix expression

void read() {
  f["NOT"] = '!';
  f["AND"] = '&';
  f["OR"] = '|';
  f["TRUE"] = '1';
  f["FALSE"] = '0';

  prio['|'] = 0;
  prio['&'] = 1;
  prio['!'] = 2;

  char line[nmax];
  in.getline(line, nmax);

  char word[nmax];
  int wordp = 0, exp = 0; //pointers in word and expression
  int i = 0;
  while (line[i] != '\0') {
    if (line[i] == ' ' || line[i] == '(' || line[i] == ')') {

      //add word from stack first
      if (0 < wordp) {
        if (1 < wordp) { //special word
          word[wordp] = '\0'; //end word
          if (f[word] == '!') {
//            cout << word << endl;
            ex[exp] = '2';
            exp++;
          }
          ex[exp] = f[word];
        } else { //just a letter
          ex[exp] = word[0];
          value[word[0]] = false;
        }
        wordp = 0; //clear stack
        exp++;
      }

      //then add the bracket, or just ignore the white space
      if (line[i] == '(' || line[i] == ')') {
        ex[exp] = line[i];
        exp++;
      }
    } else {
      word[wordp] = line[i];
      wordp++;
    }
    i++;
  }
  if (0 < wordp) {
    if (1 < wordp) { //special word
      word[wordp] = '\0'; //end word
      if (f[word] == '!') {
//        cout << word << endl;
        ex[exp] = '2';
        exp++;
      }
      ex[exp] = f[word];
    } else { //just a letter
      ex[exp] = word[0];
      value[word[0]] = false;
    }
    wordp = 0; //clear word
    exp++;
  }
  ex[exp] = '\0'; //end expression
  value['1'] = true; //everything else is false in the beginning

  n = exp;
  cout << ex << endl;
}

void infixtopostfix(char *infix, int ni, char *postfix, int &np) {
  char st[2 * nmax - 1];
  int pointer;

  np = 0;
  pointer = 0;
  for (int i = 0; i < ni; i++) {
    if (infix[i] == '(') {
      st[pointer] = infix[i];
      pointer++;
    } else if (infix[i] == ')') {
      while (0 < pointer && st[pointer - 1] != '(') {
        postfix[np] = st[pointer - 1];
        np++;
        pointer--;
      }
      pointer--;
    } else if (infix[i] == '&' || infix[i] == '|') {
      while (0 < pointer && st[pointer - 1] != '(' && prio[infix[i]] <= prio[st[pointer - 1]]) {
        postfix[np] = st[pointer - 1];
        np++;
        pointer--;
      }
      st[pointer] = infix[i];
      pointer++;
    } else if (infix[i] == '!') {
      st[pointer] = infix[i];
      pointer++;
    } else {
      postfix[np] = infix[i];
      np++;
    }
  }
  while (0 < pointer) {
    postfix[np] = st[pointer - 1];
    np++;
    pointer--;
  }

  for (int i = 0; i < np; i++) {
    cout << postfix[i] << " ";
  }
  cout << endl;
}

char makeop(char a, char op, char b) {
  bool result;
  if (op == '&') {
    result = value[a] & value[b];
  } else if (op == '|') {
    result = value[a] | value[b];
  } else if (op == '!') {
//  cout << a << op << b << endl;
    result = !value[b];
  } else {
    cout << "Error";
  }
  return result ? '1' : '0';
}

bool eval(char *postfix, int np) {
  char st[2 * nmax - 1];
  int pointer;

  for (int i = 0; i < np; i++) {
    if (postfix[i] == '&' || postfix[i] == '|' || postfix[i] == '!') {
      st[pointer - 2] = makeop(st[pointer - 2], postfix[i], st[pointer - 1]);
      pointer--;
    } else {
      st[pointer] = postfix[i];
      pointer++;
    }
  }
  return (st[0] == '1');
}

int main() {
  read();
  infixtopostfix(ex, n, postfix, npost);
  int nquery;
  in >> nquery;
  char letter;
  for (int i = 0; i < nquery; i++) {
    in >> letter;
    value[letter] = !value[letter];
    out << (int) eval(postfix, npost);
//    cout << endl;
  }
  out << endl;
  return 0;
}