Cod sursa(job #2116720)

Utilizator MastaronKatona Aron Mastaron Data 27 ianuarie 2018 21:23:16
Problema Bool Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.26 kb
#include <iostream>
#include <fstream>
#include <set>
#include <queue>
#include <stack>

using namespace std;

struct Node {
    string info;
    Node *left;
    Node *right;

    Node(string info) {
        this->info = info;
        this->left = NULL;
        this->right = NULL;
    }
};

void input(string &exp, string &mod) {
    ifstream f("bool.in");
    getline(f, exp);
    f>>mod>>mod;
    f.close();
}

void output(string out) {
    ofstream g ("bool.out");
    g << out;
    g.close();
}

bool priority(string op1, string op2) {
    if (op2 == "(") {
        return true;
    }
    if (op1 == "NOT") {
        return op2 == "AND" || op2 == "OR";
    }
    if (op1 == "AND") {
        return op2 == "OR";
    }
    return false;
}

void postfix(string exp, queue<string> &output) {
    stack<string> op;
    int space;
    int end;
    int brackets = 0;
    string item;
    bool done;

    while (!exp.empty()) {
        done = false;
        if (exp[0] == '(') {
            op.push("(");
            exp.erase(0, 1);
            brackets++;
        } else if (exp[0] == ')') {
            if (exp.length() > 1 && exp[1] == ' ') {
                exp.erase(0, 2);
            } else {
                exp.erase(0, 1);
            }
            while (op.top() != "(") {
                output.push(op.top());
                op.pop();
            }
            op.pop();
            brackets--;
        } else {
            space = exp.find(' ');
            if (brackets != 0) {
                end = exp.find(')');
                if (end != -1 && (space == -1 || space > end)) {
                    item = exp.substr(0, end);
                    exp.erase(0, end);
                    done = true;
                }
            }
            if (!done) {
                if (space == -1) {
                    item == exp;
                    exp.clear();
                } else {
                    item = exp.substr(0, space);
                    exp.erase(0, space + 1);
                }
            }

            if (item == "TRUE" || item == "FALSE" || item.length() == 1) {
                output.push(item);
            } else {
                while (!op.empty() && !priority(item, op.top())) {
                    output.push(op.top());
                    op.pop();
                }
                op.push(item);
            }
        }
    }

    while (!op.empty()) {
        output.push(op.top());
        op.pop();
    }
}

Node *tree(string exp) {
    queue<string> output;
    stack<Node *> build;
    postfix(exp, output);
    string item;
    Node *node;

    while (!output.empty()) {
        item = output.front();
        if (item == "TRUE" || item == "FALSE" || item.length() == 1) {
            build.push(new Node(item));
        } else {
            if (item == "NOT") {
                node = new Node("NOT");
                node->left = build.top();
                build.pop();
                build.push(node);
            } else {
                node = new Node(item);
                node->left = build.top();
                build.pop();
                node->right = build.top();
                build.pop();
                build.push(node);
            }
        }
        output.pop();
    }

    return build.top();
}

void print(Node *node) {
    if (node->left != NULL) {
        print(node->left);
    }
    cout << node->info << " ";
    if (node->right != NULL) {
        print((node->right));
    }
}

bool execute(Node *node, set<string> val) {
    if (node->info == "AND") {
        return execute(node->left, val) && execute(node->right, val);
    } else if (node->info == "OR") {
        return execute(node->left, val) || execute(node->right, val);
    } else if (node->info == "NOT") {
        return !execute(node->left, val);
    } else if (node->info == "TRUE") {
        return true;
    } else if (node->info == "FALSE") {
        return false;
    } else {
        return val.count(node->info) == 1;
    }
}

int main() {
    string exp, mod, e, out;
    set<string> val;
    Node *root;

    input(exp, mod);
    root = tree(exp);
    //print(root);

    for(auto c : mod) {
        e = string(1, c);
        if(val.count(e)) {
            val.erase(e);
        } else {
            val.insert(e);
        }
        out += execute(root, val) + '0';
    }

    output(out);
    return 0;
}