zstu4189——后缀表达式——逻辑运算
Description
还记得大学里学过的模电么,今天就让我们将与或非变成一道题吧。
给你一个与或非的表达式,求出这个表达式的值,表达式总共有八种字符。
三种逻辑运算符按照优先级排列如下。
‘!’:表示取反。
‘&’:逻辑与。
‘|’:逻辑或。
两个字符‘T’,‘F‘分别表示true和 false。
另外还有左右括号,空格三种字符。跟一般的表达式一样,括号可以改变优先级。
Input
每组数据输入一行字符串,字符串长度小于等于100.
Output
输出一个数0或1,表示逻辑表达式的答案。
Sample Input
T
Sample Output
1
HINT
Source
大意:代码能力要求很高
肉鸽的递归做法:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; char s[123]; int n; int work0(int l, int r); int find(int l){ int cnt = 0; for(int i = l; i < n; i ++){ if(s[i] == '(') cnt ++; else if(s[i] == ')') cnt --; if(cnt == -1) return i; } } int work(int l, int r){ //printf("l = %d, r = %d\n", l, r); for(int i = l; i <= r; i ++){ if(s[i] == '(') { int ri = find(i+1); int k = work0(i+1, ri-1); // printf("k = %d\n", k); return k; } if(s[i] == '!') { for(int j = i+1; j <= r; j ++){ if(s[j] == ' ') continue; else if(s[j] == 'T') { return 0; }else if(s[j] == 'F') { return 1; } else if(s[j] == '('){ int ri = find(j+1); return 1^work0(j+1, ri-1); } } }else if(s[i] == 'F') return 0; else if(s[i] == 'T') return 1; } return 0; } int work1(int l, int r){ int cnt = 0; for(int i = l; i <= r; i ++){ if(s[i] == '(' ) cnt ++; if(s[i] == ')') cnt --; if(s[i] == '&' && cnt == 0) return work1(l, i-1) & work1(i+1, r); } return work(l, r); } int work0(int l, int r){ int cnt = 0; for(int i = l; i <= r; i ++){ if(s[i] == '(' ) cnt ++; if(s[i] == ')') cnt --; if(s[i] == '|' && cnt == 0) { return work0(l, i-1) | work0(i+1, r); } } return work1(l, r); } int main(){ while(gets(s) != NULL){ n = strlen(s); printf("%d\n", work0(0, n-1)); } return 0; } /* !(T|F)|((T|F)&T) F&T&F|T|T|F|!F */
铭神的模拟栈,后缀表达式做法:
#include<cstdio> #include<cstring> const int MX = 3110; char s[MX]; struct Exp { char op[MX]; int num[MX]; int top,tot; void inti() { top = 0; tot = 0; memset(op,0,sizeof(op)); memset(num,0,sizeof(num)); op[0] = '('; } int calc(char k,int a,int b) { if(k == '&'){ return a && b; } else if( k == '|') return a || b; } bool prior(char a,char b) { if(b == '|') return a!='('; if(b == '&'){ return a == '!' || a == '&'; } return false; } void solve() { int len = strlen(s); s[len++] = '('; for(int i = 0 ; i < len;i++){ if(s[i] == ' ') continue; else if(s[i] == '(') op[++top] = '('; else if(s[i] == ')'){ if(top > 0 && op[top] != '('){ if(op[top] == '!'){ num[tot] = !num[tot]; top--; } else { num[tot-1] = calc(op[top],num[tot-1],num[tot]); tot--; top--; } } top--; } else if(s[i] == 'T' || s[i] == 'F') num[++tot] = s[i] == 'T' ? 1 : 0; else { while(top > 0 && prior(op[top],s[i])){ if(op[top] == '!'){ num[tot] = !num[tot]; top--; } else { num[tot-1] = calc(op[top],num[tot-1],num[tot]); tot--; top--; } } op[++top] = s[i]; } } printf("%d\n",num[1]); } }; Exp E; int main() { while(gets(s)!=NULL){ E.inti(); E.solve(); } return 0; }