Cod sursa(job #1512643)

Utilizator gallexdAlex Gabor gallexd Data 28 octombrie 2015 13:46:47
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <iostream>
#include <cstdio>
#include <string.h>

struct Node {
    Node(char op, Node *left, Node *right);

    char op;
    Node *left, *right;
};

Node *evalExpression(int level);
Node *getOperand();
void skipSpaces();

bool evalTree(Node *n);

char priority[2][4] = {"OR", "AND"};
bool values[27];

char exp[1010];
char *p = exp;
int N;
using namespace std;

Node* evalExpression(int level) {
    Node *result;
    if (level == 2)
        return getOperand();
    result = evalExpression(level+1);
    size_t opLen = strlen(priority[level]);
    while (strncmp(p, priority[level], opLen) == 0) {
        p += opLen;
        result = new Node(priority[level][0], result, evalExpression(level+1));
    }
    return result;
}

Node *getOperand() {
    skipSpaces();
    Node *result;
    if (strncmp(p, "NOT", 3) == 0) {
        p += 3;
        result = new Node('N', getOperand(), NULL);
    } else if (*p == '(') {
        ++p;
        skipSpaces();
        result = evalExpression(0);
        skipSpaces();
        ++p;
    } else if (strncmp(p, "TRUE", 4) == 0) {
        p += 4;
        result = new Node('T', NULL, NULL);
    } else if (strncmp(p, "FALSE", 5) == 0) {
        p += 5;
        result = new Node('F', NULL, NULL);
    } else {
        result = new Node(*p - 'A' + 1, NULL, NULL);
        ++p;
    }
    skipSpaces();
    return result;
}

void skipSpaces() {
    while (*p == ' ') ++p;
}

int main () {

    freopen("bool.in", "r", stdin);
    freopen("bool.out", "w", stdout);

    cin.getline(exp, 1010);
    Node *tree = evalExpression(0);
    cin >> N;
    char c;
    bool r;
    for (int i=0; i<N; ++i) {
        cin >> c;
        values[c-'A'+1] = ! values[c-'A'+1];
        r = evalTree(tree);
        printf("%hd", r);
    }
    printf("\n");
    return 0;
}

bool evalTree(Node *n) {
    switch (n->op) {
        case 'O': return evalTree(n->left) || evalTree(n->right);
        case 'A': return evalTree(n->left) && evalTree(n->right);
        case 'N': return !evalTree(n->left);
        case 'T': return true;
        case 'F': return false;
        default:
            return values[n->op];
    }
}

Node::Node(char op, Node *left, Node *right) {
    this->op = op;
    this->left = left;
    this->right = right;
}