Pagini recente » Cod sursa (job #1054977) | Cod sursa (job #2067739) | Cod sursa (job #1375487) | Cod sursa (job #853560) | Cod sursa (job #1067216)
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <map>
#define CONST 0
#define VAR 1
#define OPERATOR 2
#define NOT 3
#define OR 4
#define AND 5
using namespace std;
std::map<char, bool> truth_table;
struct Node {
int type;
int val;
Node* left;
Node* right;
Node(int type, int val, Node* left, Node* right) : type(type), val(val),
left(left), right(right) {}
};
bool eval(Node* root) {
switch (root->type) {
case CONST:
return root->val;
case VAR:
return truth_table[root->val];
case OPERATOR:
switch (root->val) {
case NOT:
return !eval(root->right);
case AND:
return eval(root->left) && eval(root->right);
case OR:
return eval(root->left) || eval(root->right);
default:
std::cerr << "Unknown operator!" << std::endl;
}
default:
std::cerr << "Unknown node typ!" << std::endl;
}
}
int get_priority(std::string& token) {
if (token == "NOT") {
return 1;
} else if (token == "AND") {
return 2;
} else if (token == "OR") {
return 3;
}
}
int get_operator(std::string& token) {
if (token == "NOT") {
return NOT;
} else if (token == "AND") {
return AND;
} else if (token == "OR") {
return OR;
}
}
Node* rparse(std::vector<string>& tokens, int first, int last) {
if (first > last) {
return NULL;
} else if (first == last) {
// Base case.
if (tokens[first] == "TRUE" || tokens[first] == "FALSE") {
return new Node(CONST, (tokens[first] == "TRUE") ? 1 : 0, NULL, NULL);
} else if (tokens[first].size() == 1) {
return new Node(VAR, tokens[first][0], NULL, NULL);
} else {
std::cerr << "Wrong parse tree!" << std::endl;
exit(1);
}
} else {
// Find the least priority operator outside all parantheses.
int index = -1;
int priority = -1;
int nopen = 0;
for (int i = first; i <= last; ++i) {
if (tokens[i] == "(") {
nopen++;
} else if (tokens[i] == ")") {
nopen--;
} else if (tokens[i] == "NOT" ||
tokens[i] == "AND" ||
tokens[i] == "OR") {
if (nopen == 0 && (priority == -1 ||
priority > get_priority(tokens[i]))) {
index = i;
priority = get_priority(tokens[i]);
}
}
}
if (index == -1) {
return rparse(tokens, first + 1, last - 1);
}
return new Node(OPERATOR,
get_operator(tokens[index]),
rparse(tokens, first, index - 1),
rparse(tokens, index + 1, last));
}
}
Node* parse(std::string& nline) {
// Create a new line in which you insert space before and after each
// paranthesis.
std::string line;
for (int i = 0; i < nline.size(); ++i) {
if (nline[i] == ')' || nline[i] == '(') {
line.append(" ").append(std::string(1, nline[i])).append(" ");
} else {
line.append(std::string(1, nline[i]));
}
}
// Break the line into tokens.
std::vector<string> tokens;
char* buffer = strdup(line.c_str());
for (char* p = strtok(buffer, " \t\n"); p; p = strtok(NULL, " \t\n")) {
if (*p) {
tokens.push_back(std::string(p));
}
}
delete buffer;
// Recursively parse the tokens.
return rparse(tokens, 0, tokens.size() - 1);
}
int main()
{
std::ifstream in("bool.in");
std::ofstream out("bool.out");
std::string line;
std::getline(in, line);
// Parse the boolean expression.
Node* expr = parse(line);
int n;
in >> n;
std::string vars;
in >> vars;
// Initialize the truth table.
for (int var = 'A'; var <= 'Z'; ++var) {
truth_table[var] = false;
}
// Run the evaluation.
for (int i = 0; i < vars.size(); ++i) {
truth_table[vars[i]] = !truth_table[vars[i]];
if (eval(expr)) {
out << "1";
} else {
out << "0";
}
}
out << std::endl;
in.close();
out.close();
return 0;
}