#include<bits/stdc++.h>
using namespace std;
struct treeNode{
treeNode *lc;
treeNode *rc;
bool value;
int op1;
int op2;
char data;
treeNode(char c):data(c),lc(0),rc(0),value(0),op1(0),op2(0){
}
treeNode():lc(0),rc(0),value(0),op1(0),op2(0){
}
};
treeNode *root;
stack<treeNode*> jd;
stack<char> ysf;
string s;
void ys(){
treeNode *node,*n1,*n2;
n2=jd.top();
jd.pop();
n1=jd.top();
jd.pop();
node=new treeNode(ysf.top());
ysf.pop();
node->lc=n1;
node->rc=n2;
jd.push(node);
}
/*
建树过程:
第一阶段:扫描字符串
1.当前字符为0或1,则建立treeNode节点,压入栈jd。
2.当前字符为|或者&运算符:每收到一个运算符之前看一下当前ysf栈顶元素的优先级是否高于当前运算符
如果是,则弹出ysf栈顶元素,建立分支节点。然后jd栈做两次出栈操作,添加为分支节点的左孩子和右孩子(见ys函数)
然后,当前运算符压入栈ysf。
3.如果当前节点为(,压入ysf即可
4.如果当前节点为) ,做括号内的运算,建立分支节点。最后弹出(
第二阶段:清空ysf栈
只要ysf栈不为空,调用ysf建立分支节点
这个过程,栈底元素较后运算,对应在表达式树的位置离根节点更近。
最后返回根节点。
*/
treeNode* buildTree(){
treeNode *node,*n1,*n2;
int i=0;
while(i<s.size()){
if(s[i]=='0'||s[i]=='1'){
node=new treeNode(s[i]);
jd.push(node);
}
else if(s[i]=='('){
ysf.push('(');
}
else if(s[i]==')'){
treeNode *n1,*n2;
while(ysf.top()!='('){
ys();
}
ysf.pop();
}
else if(s[i]=='|'){
while(ysf.size()>0&&ysf.top()!='('){
ys();
}
ysf.push(s[i]);
}
else if(s[i]=='&'){
while(ysf.size()>0&&ysf.top()=='&'){
ys();
}
ysf.push(s[i]);
}
i++;
}
while(ysf.size()>0){
ys();
}
return jd.top();
}
/*
通过二叉树先序遍历,求值。
如果短路,父节点的与运算和或运算的短路次数只与左孩子的与运算和或运算短路次数有关。
否则, 父节点的短路次数与左孩子、右孩子相关操作次数都有关。
*/
void traverseTree(treeNode *r){
if(r->data=='1') {
r->value=1;
return;
}
else if(r->data=='0') return;
else{
traverseTree(r->lc);
traverseTree(r->rc);
if(r->data=='|'){
r->value=(r->lc->value)|(r->rc->value);
if(r->lc->value) {
r->op2=r->lc->op2+1;
r->op1=r->lc->op1;
}
else{
r->op2=r->lc->op2+r->rc->op2;
r->op1=r->lc->op1+r->rc->op1;
}
}
else{
r->value=(r->lc->value)&(r->rc->value);
if(r->lc->value==0){
r->op1=r->lc->op1+1;
r->op2=r->lc->op2;
}
else{
r->op2=r->lc->op2+r->rc->op2;
r->op1=r->lc->op1+r->rc->op1;
}
}
}
}
int main(){
getline(cin,s);
root=buildTree();
traverseTree(root);
cout<<root->value<<endl;
cout<<root->op1<<" "<<root->op2;
return 0;
}
11-03
1237
1237
02-06
3269
3269
01-15
641
641
02-22
399
399
03-04
242
242
08-12
1993
1993

被折叠的 条评论
为什么被折叠?



