题解 P1575 正误问题
解题思路:
考虑模拟,先将字符串式的读入转换成数组方便处理,同时处理逻辑 not,然后就像普通的多项式求值一样处理 and 和 or。
具体的,用一个栈维护当前剩下的布尔值,对于 or 直接丢进去,最后统一处理,对于 and 将栈顶与序列中的下一个值进行 and 运算。
这里会发现一个问题,就是查找下一个值得时候可能会有 not,导致写起来比较困难,可以先将所有的 not 处理掉,然后在下一次循环中直接往后取值。
对于表达式错误的判断有且仅有以下几条:
- not 后跟运算符;
- 连续的运算符或布尔值;
- 最后一个是 not 或运算符,即没有布尔值对应。
实现上:特判第三点;处理 not 时同时判断第一点;对于第二点,使用一个值对应上一个非 not 符号是运算符还是布尔值,然后处理时直接判断。这些操作都可以再依次循环中解决。
注意可能出现连续的 not,这样是正确的。
代码:
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
string a;
int s[1005],len,last,st[1005],top,ans;
int main(){
while(cin>>a){
len++;
if(a=="true")s[len]=1;
if(a=="false")s[len]=0;
if(a=="or")s[len]=2;
if(a=="and")s[len]=3;
if(a=="not")s[len]=4;
}
s[len+1]=2;
for(int i=1;i<=len;i++){
if(s[i]==1||s[i]==0){
if(last==1)return printf("error\n")&0;
last=1;
}
else
if(s[i]==4){
if(s[i+1]==2||s[i+1]==3)return printf("error\n")&0;
else{
bool b=1;
while(s[i+1]==4)i++,b^=1;
s[i+1]=b^s[i+1];
}
}
else{
if(last==0)return printf("error\n")&0;
last=0;
}
}
for(int i=1;i<=len;i++){
if(s[i]==0||s[i]==1)top++,st[top]=s[i];
if(s[i]==3)st[top]&=s[i+1],i++;
}
for(int i=1;i<=top;i++){
ans|=st[i];
}
if(ans)
printf("true\n");
else
printf("false\n");
return 0;
}