Pagini recente » Cod sursa (job #18263) | Cod sursa (job #1931644) | Cod sursa (job #1029963) | Cod sursa (job #2453418) | Cod sursa (job #1827914)
//Bool cu arbori de derivare
#include <iostream>
#include <fstream>
#include <string>
#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;
struct tree {
char val;
tree *left;
tree *right;
};
tree *root;
int n;
char ex[nmax]; //expression to be evaluated
void read() {
f["NOT"] = '!';
f["AND"] = '&';
f["OR"] = '|';
f["TRUE"] = '1';
f["FALSE"] = '2';
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
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
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;
}
int prevop[prmax][nmax];
int lastvisited[prmax][nmax];
void precompute() {
//daca nu merge pun lastvisited afara
//lastvisited[prioritate][nestinglevel]
//daca parcurg de la stanga la dreapta => pot sa updatez: prevop
for(int i=0; i<n; i++) {
for(int k=0; k<prmax; k++) {
lastvisited[k][i] = -1;
}
}
int nestinglevel = 0;
//O(n)
for(int i = 0 ; i < n ; i++){ //1+2+3+4
if(ex[i] == '(') {//1+(2+3)
for(int k = 0 ; k < prmax ; k++){
prevop[k][i] = lastvisited[k][nestinglevel];
}
nestinglevel++;
} else if(ex[i] == ')') {
nestinglevel--; //2+(3-4)+5
for(int k = 0 ; k < prmax ; k++){
prevop[k][i] = lastvisited[k][nestinglevel];
}
} else {
for(int k = 0 ; k < prmax ; k++){
prevop[k][i] = lastvisited[k][nestinglevel];
}
if(!(ex[i]=='1' || ex[i] == '0' || (ex[i]>='A' && ex[i] <='Z')))
lastvisited[prio[ex[i]]][nestinglevel] = i;
}
}
}
tree* buildtree(int from, int to) { //1 A B 0
//(1|2)&(3|4)
tree *result = nullptr;;
//1 +2 +(3 +4)+5
if(prevop[0][to] < from && prevop[1][to] < from && prevop[2][to] < from && from != to) {
result = buildtree(from + 1, to - 1);
} else if(from == to){
result = new tree(); // 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[from];
result->left = nullptr;
result->right = nullptr;
//cout<<":";
} else {
if(from <= prevop[0][to]){ ///1+2+(3+4)+5
///il luam
result = new tree(); /// 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[prevop[0][to]];
///il despartim
result->left = buildtree(from, prevop[0][to]-1); //3+5
//cout<<":";
result->right = buildtree(prevop[0][to]+1 ,to);
//cout<<"|";
} else if(from <= prevop[1][to]){
///il luam
result = new tree(); /// 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[prevop[1][to]];
///il despartim
// cout<<"->("<<from<<", "<<to<<")"<<endl;
// cout<<from<<" "<<prevop[1][to]-1<<endl;
result->left = buildtree(from, prevop[1][to]-1); //3+5
//cout<<prevop[1][to]+1<<" "<<to<<endl;
result->right = buildtree(prevop[1][to]+1 ,to);
} else{ //avem !!!A
// cout<<ex[from]<<" "<<from<<" "<<to<<'\n';
assert(ex[from] == '!');
result = new tree(); // 10001 - 20001; 10001 - 15001; 17345 -> result
result->val = ex[from];
result->left = nullptr;
result->right = buildtree(from + 1 ,to);
}
}
return result;
}
bool eval(tree *node){ //O(n)
if(node->val == '&') {
return eval(node->left) & eval(node->right);
} else if(node->val == '|') {
return eval(node->left) | eval(node->right);
} else if(node->val == '!'){
return !eval(node->right);
} else {
return value[node->val];
}
}
int main() {
read(); //A&B|C|!D|(1&0)
precompute();
root = buildtree(0, n - 1); //0
//citire
int ntest;
in >>ntest;
char c;
for(int i = 0 ; i < ntest ; i++){
in>>c;
value[c] = !value[c];
out<<(int)eval(root);
}
return 0;
}