WUSTOJ 1641 布尔表达式的计算【栈和队列】

题目来源于 http://acm.wust.edu.cn/problem.php?id=1641&soj=0
123
这题要用到栈(当然直接用数组用可以的,所以我就写了2种代码,上面的是数组写的qwq)
**

思路:

开2个数组。num记录数值 T为1,F为0;sign记录符号 !为3,&为2,|为1,(为0,至于)是与 ( 呼应的标志,具体看代码 。然后定义了2个函数。getnum用于把T、F变成数值1、0,顺便处理符号!;twosum进行双目运算,处理&和|。最后结果就是num[0]。

注意:

!是单目运算符,&和|是双目运算符。(扩展一下 ? : 是三目运算符)
最后字符串读完之后还要判断一下sign是否为空,可以用 T&F 样例解释,我就不多说了

代码:

#include<bits/stdc++.h> 
using namespace std; 
const int maxn=105; 
int num[maxn],sign[maxn]; 
char s[maxn]; 
int flagn,flags; //flagn是num数组的标志,flags是sign数组的标志
void getnum(int x) //获得T F数值
{ 
    while(flags&&sign[flags-1]==3){ //处理符号!
        x=!x;
        flags--; 
    } 
    num[flagn++]=x; 
} 
void twosum() //双目运算,处理符号&和|
{ 
    int x=num[--flagn]; 
    int y=num[--flagn]; 
    int ss=sign[--flags]; 
    int z=(x&y); 
    if(ss==1) z=(x|y); 
    getnum(z); 
} 
int main() 
{ 
    int times=1; 
    while(gets(s)!=NULL){ 
        int len=strlen(s); 
        flagn=flags=0; 
        for(int i=0;i<=len-1;i++){ 
            if(s[i]=='T') getnum(1); 
            else if(s[i]=='F') getnum(0); 
            else if(s[i]=='|'){ 
            (flags&&sign[flags-1]>=1)  twosum(); 
                sign[flags++]=1; 
            } 
            else if(s[i]=='&'){ 
                while(flags&&sign[flags-1]>=2)  twosum(); 
                sign[flags++]=2; 
            } 
            else if(s[i]=='!')  sign[flags++]=3; 
            else if(s[i]=='(')  sign[flags++]=0; 
            else if(s[i]==')'){    //处理符号()
                while(flags&&sign[flags-1])  twosum(); 
                flags--; 
                getnum(num[--flagn]); 
            } 
        } 
        while(flags) twosum();   //别忘了这里
        printf("Expression %d:%c\n",times++,num[0]?'T':'F'); 
    } 
    return 0;
} 

下面是用栈写的,好像有点麻烦awa,巨佬们见笑了qwq

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
char s[maxn];
stack<int> num,sign;
void getnum(int x) //获得T F数值
{
    while(!sign.empty()&&sign.top()==3){    //处理符号!
        x=!x;
        sign.pop();
    }
    num.push(x);
}
void twosum() //双目运算,处理符号&和|
{
    int x=num.top();
    num.pop();
    int y=num.top();
    int ss=sign.top();
    num.pop();sign.pop();
    int z=(x&y);
    if(ss==1) z=(x|y);
    getnum(z);
}
int main()
{
    int times=1;
    while(gets(s)!=NULL){
        int len=strlen(s);
        while(!num.empty()) num.pop();
        while(!sign.empty())  sign.pop();
        for(int i=0;i<=len-1;i++){
            if(s[i]=='T') getnum(1);
            else if(s[i]=='F') getnum(0);
            else if(s[i]=='|'){
                while(!sign.empty()&&sign.top()>=1)  twosum();
                sign.push(1);
            }
            else if(s[i]=='&'){
                while(!sign.empty()&&sign.top()>=2)  twosum();
                sign.push(2);
            }
            else if(s[i]=='!')  sign.push(3);
            else if(s[i]=='(')  sign.push(0);
            else if(s[i]==')'){    //处理符号()
                while(!sign.empty()&&sign.top()!=0)  twosum();
                sign.pop();
                int t=num.top();
                num.pop();
                getnum(t);
            }
        }
        int x;
        while(!sign.empty()) twosum();    //别忘了这里
        while(!num.empty()) {x=num.top(); num.pop();}   //获得栈底
        printf("Expression %d:%c\n",times++,x?'T':'F');
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43890662/article/details/87191071