ZSTU OJ 4189 逻辑运算(逆波兰式)

2019-04-13 15:19发布

Description

 还记得大学里学过的模电么,今天就让我们将与或非变成一道题吧。 给你一个与或非的表达式,求出这个表达式的值,表达式总共有八种字符。 三种逻辑运算符按照优先级排列如下。 ‘!’:表示取反。 ‘&’:逻辑与。 ‘|’:逻辑或。 两个字符‘T’,‘F‘分别表示true和 false。 另外还有左右括号,空格三种字符。跟一般的表达式一样,括号可以改变优先级。  

Input

每组数据输入一行字符串,字符串长度小于等于100.

Output

 输出一个数0或1,表示逻辑表达式的答案。

Sample Input

T

Sample Output

1

逆波兰式简单应用=-=注意!是单目运算,&和|是双目运算

#include #include #include #include #include #include #include #include #include #include #include using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) typedef long long LL; typedef pairpil; const int INF = 0x3f3f3f3f; stacks; stackval; char str[1100]; int ok(char c) { if(c=='!') return 3; if(c=='&') return 2; if(c=='|') return 1; else return 0; } int cal(int x1,int x2,char c) { if(c=='&') return x1&&x2; if(c=='|') return x1||x2; } void solve() { int x1=val.top();val.pop(); int x2=val.top();val.pop(); int x=cal(x1,x2,s.top()); s.pop();val.push(x); } int main() { s.push('#'); while(gets(str)) { while(!val.empty()) val.pop(); int len=strlen(str); REP(i,len) { if(str[i]==' ') continue; else if(str[i]=='T'||str[i]=='F') val.push(str[i]=='T'?1:0); else if(str[i]=='(') s.push('('); else if(str[i]==')') { while(s.top()!='(') { if(s.top()!='!') solve(); else { int x=val.top(); val.pop();val.push(!x); s.pop(); } } s.pop(); } else { while(ok(s.top())>=ok(str[i])) { if(s.top()!='!') solve(); else { int x=val.top(); val.pop();val.push(!x); s.pop(); } } s.push(str[i]); } } while(s.top()!='#') { if(s.top()!='!') solve(); else { int x=val.top(); val.pop();val.push(!x); s.pop(); } } printf("%d ",val.top()); } return 0; } /* !(T&F) */