6263:布尔表达式
- 6263:布尔表达式
- 优先级打表
- 思路传送门
6263:布尔表达式
#include <bits/stdc++.h>
using namespace std;
#include <iomanip>
map<char,int> mp;
char piority[7][7]={
//行是操作数栈中的栈顶操作符,看优先级是否大于遍历表达式之后遇到的运算符
// | & ! ( ) #
{'>','<','<','<','>','>'}, //|
{'>','>','<','<','>','>'}, //&
{'>','>','=','<','>','>'}, //!
{'<','<','<','<','=','0'}, //(
{'>','>','>','>','0','>'}, //)
{'<','<','<','<','0','='} //#
};
// ((<
// )(>栈顶操作符是先遇到的操作符,如果可以出栈,说明栈顶操作符
//优先级大,并不代表后面表达式遇见的不要入栈,
// 即,后面遇见的要入栈不能说明栈顶优先级小
string removespace(string str){
string s="";
int len=str.size();
for(int i=0;i<len;i++){
if(str[i]!=' ')s+=str[i];
}
return s;
}
char cmp(char r,char c){
int row=mp[r];
int col=mp[c];
return piority[row][col];
}
void solve(string s){
char op[100];//操作符
bool num[100];
//布尔值0或1表示,本来bool类型也可,!操作不用~,用1-num[ntop]
int otop=0,ntop=0;
op[otop++]='#';
//用于表示优先级最小的操作符,省的判断栈空或表达式最后遇到空格
//不知如何比较
int len=s.size();
for(int i=0;i<len;i++){
if(s[i]=='V')num[ntop++]=1;
else if(s[i]=='F')num[ntop++]=0;
else {//那就是操作符了
char c=s[i];
char r=op[otop-1];
char res=cmp(r,c);
while(res=='>'){
r=op[otop-1];//不写这句就不对了,栈顶元素经过这个循环会改变
otop--;//出栈
switch(r){
case '&':num[ntop-2]=num[ntop-1]&num[ntop-2];ntop--;break;
case '|':num[ntop-2]=num[ntop-1]|num[ntop-2];ntop--;break;
case '!':num[ntop-1]=1-num[ntop-1];break;
}
res=cmp(op[otop-1],c);
}
if(res=='=')otop--;//两个操作符抵消,表达式的继续向前遍历
if(res=='<')op[otop++]=s[i];
}
}
if(num[0]==0)cout<<"F"<<endl;
else cout<<"V"<<endl;
}
int main(){
mp['|']=0;mp['&']=1;mp['!']=2;mp['(']=3;mp[')']=4;mp['#']=5;
string str;
while(getline(cin,str)){//cin.getline(s,len)字符数组
string s=removespace(str);
s+='#';
solve(s);
}
return 0;
}
优先级打表
碰到运算数可以直接输出 一开始在表达式中遇到的运算符都不能轻易去进行运算(考虑到运算符的优先级,后面可能存在优先级比我高的),而是依次保存在栈中,直到继续遍历表达式,遇到了优先级小于操作符栈顶元素的运算符,于是将操作符中操作符出栈进行运算,直到栈顶操作符优先级小于该遇到的操作符,将该操作符入栈
特别的:
铭记是个比较无敌的存在,但是当 遍历表达式遇到的±*/&|与操作符栈顶的
一个铁律:操作符栈中操作符的优先级 大于 表达式后来遇到的操作符才能出栈
1、对于左括号,遍历表达式遇到左括号,优先级一定大于操作符栈顶元素
(相比,(的优先级又是最小的,表达式遇到的操作符入栈
2、不久后少不了),括号里的都处理完了,栈顶元素一个一个弹出直到(,
也就是)的优先级最小
3、栈顶元素和表达式遇到的操作符优先级相同,则算栈顶的优先级更大,因为
先遇到他
4、优先级相等的情况就直接出栈,而表达式当即遇到的操作符也是不能进行
任何操作的(除了入栈,接着就是往后遍历,so优先级相等相当于两个
符号碰撞抵消,有!!,(),##