Boolean Expressions

首先声明此题后台可能极水(毕竟这种数据不好造!)。昨天写了一天却总是找不到bug,讨论区各种数据都过了,甚至怀疑输入有问题,但看到gets也可以过,难道是思路错了?

题意:V表示ture,F表示false,然后有三种位运算符‘!’、‘&’、'|'。其中'!'的优先级最高,‘|’的优先级最低。即优先级关系:! > & > | 。给你一串包含这些运算符的表达式当然了还有括号,要你判断最终结果是VorF。

先说说我的思路吧:符号栈和数值栈肯定是前提(数组模拟也无所谓)。由于‘!’和‘&’的运算等级较高,于是我们可以先把所有的‘!’和‘&’先进行运算,最后运算或(扫一遍无先后)。当然了,括号的优先级最最高,我们特判括号的情况。你可能要问‘!’和’&‘的优先级有大小,怎么判断先后呢,我们发现’!‘一般是在一个数值前面,当存入一个数值的时候可以直接运算,’&‘在两个数值之间,也是直接取数值栈顶的两个元素直接运算再入栈。就是因为’!‘只能在一个数值前或者括号前(括号内最终也会化为一个数值),所以如果’!‘和’&‘都出现了肯定会将’!‘先运算完再’&‘运算,本来也符合题意优先级之分。但为什么会wa这么多遍呢,next....

现在来说说括号怎么判,我们如果是出现'('的话直接先入符号栈,然后数值和符号也是直接入相应的栈再判断运算。但当’)‘出现意味着肯定有一个最近的’(‘与其配对,我们这时就要把括号里的先运算完对吧,但上述提到’!‘和’&‘都是一出现就直接运算了,所以这时的括号内只能是单个数值或很多’|‘,还是直接运算,到’(‘就截止了嘛。最后弹出’(‘。好像看起来没毛病,又是WA。原因为何?next.....

最后看其他人提交的代码结果发现他们根本没有判优先级,三种符号出现都是从左往右扫,这样也过?’!‘的情况肯定没问题,但’&‘和’|‘总得有个先后,一学弟给出一幅图画出单个’&‘和单个’|‘的所有情况让我猜想这样依次运算是否和先后运算的结果一样?草草的证明了一下貌似真的可以(急功近利),然后仿照这大家的思路做了做终于发现自己的问题出在哪了,原来在进行’!‘和’&‘运算的时候没有判断到’(‘应截止。还有在’(‘应当出栈的时候没有判断栈顶元素是否为’(‘。也是神奇,我的正确思路居然被这种样例hackde。这时仍接受着依次运算和先后运算的结果一样的观点,回到宿舍学姐再讨论群里提出这样一组数据:1|0&0 即 V|F&F。这样明显打破上述观点,然后用两种代码都试了试果然依次运算的结果是F,正解应该是V。不得不说自己没有仔细证明为了A题草草下定结论,不过所幸自己的代码是没有问题的。可能大家读题题意没有明确,却阴差阳错,集训队的读题能力貌似一直处于迷离状态。。。。

重(ji)点(tang):研究性学习真的是让人很兴奋,充分锻炼一个人的耐心与思维,在结论成果得出的那一刻仿佛即将升天般的快感,这种学习方式也值得我们利用,当前学习状态不禁让我想起了快餐文化这一概念,急功近利总不得有好的结果,沉心静气淡泊名利才能走的更远。不惜花了这么大的篇幅来引出这段话,就算个人体验了,不喜勿喷。

回到原题,下面给出三种代码:

思路1:WA。未正确判断好括号关系。

const int N=1e6+10;
stack<char>q1;
stack<int>q2;
char s[150];
void ch(char c)
{if(c=='!'){int x1=q2.top();q2.pop();x1=!x1;q2.push(x1);}else if(c=='&'){int x1=q2.top();q2.pop();int x2=q2.top();q2.pop(); q2.push(x1&x2);}else if(c=='|'){int x1=q2.top();  q2.pop();int x2=q2.top();  q2.pop();q2.push(x1|x2);}q1.pop();
}
int main()
{int t=1;char c;while(1){c=getchar();if(c==' ') continue;if(c=='\n'||c==EOF){while(!q1.empty()){if(q1.top()!='(') ch(q1.top());else q1.pop();}printf("Expression %d: ",t++);if(q2.top()==1) puts("V");else puts("F");while(!q1.empty()) q1.pop();while(!q2.empty()) q2.pop();if(c==EOF) break;else continue;}if(c==')'){while(!q1.empty()&&q1.top()!='(') ch(q1.top());q1.pop();//本意是删去‘(’,但应该判断是否为空且栈顶是否为‘(’}else{if(c!='V'&&c!='F') q1.push(c);else{if(c=='V') q2.push(1);else q2.push(0);while(!q1.empty())//应该判断‘(’截止{if(q1.top()!='!'&&q1.top()!='&') break;//‘!’和'&'优先ch(q1.top());}}}}return 0;
}

代码二:AC。

const int N=1e6+10;
stack<char>q1;
stack<int>q2;
char s[N];
void ch(char c)
{if(c=='!'){int x=q2.top();q2.pop();q2.push(!x);}else if(c=='&'){int x1=q2.top();q2.pop();int x2=q2.top();q2.pop();q2.push(x1&x2);}else if(c=='|'){int x1=q2.top();q2.pop();int x2=q2.top();q2.pop();q2.push(x1|x2);}q1.pop();
}
int main()
{int t=1;while(gets(s)){while(!q1.empty()) q1.pop();while(!q2.empty()) q2.pop();int len=strlen(s);for(int i=0; i<len; i++){if(s[i]==' ') continue;if(s[i]==')'){while(!q1.empty()&&q1.top()!='(')  ch(q1.top());if(!q1.empty()&&q1.top()=='(') q1.pop();//删去左括号}else{if(s[i]!='F'&&s[i]!='V') q1.push(s[i]);else{if(s[i]=='F') q2.push(0);else q2.push(1);while(!q1.empty()&&q1.top()!='('){if(q1.top()!='&'&&q1.top()!='!') break;ch(q1.top());}if(!q1.empty()&&q1.top()=='(') q1.pop();}}}printf("Expression %d: ",t++);while(!q1.empty()) ch(q1.top());if(q2.top()==1) puts("V");else puts("F");}return 0;
}

代码三:hacked   V|F&F

const int N=1e3+10;
stack<char>q1;
stack<int>q2;
char s[N];
void deal(char tmp)
{if(tmp==')') q1.pop();else{if(tmp=='V') q2.push(1);else q2.push(0);}while(!q1.empty()&&q1.top()!='('){char c=q1.top();q1.pop();if(c=='!'&&!q2.empty()){int x=q2.top();q2.pop();q2.push(!x);}else if(c=='&'&&q2.size()>1){int x1=q2.top();q2.pop();int x2=q2.top();q2.pop();q2.push(x1&x2);}else if(c=='|'&&q2.size()>1){int x1=q2.top();q2.pop();int x2=q2.top();q2.pop();q2.push(x1|x2);}}
}
int main()
{int t=1;while(gets(s)){while(!q1.empty()) q1.pop();while(!q2.empty()) q2.pop();int len=strlen(s);for(int i=0; i<len; i++){if(s[i]==' ') continue;if(s[i]=='F'||s[i]=='V'||s[i]==')') deal(s[i]);else q1.push(s[i]);}printf("Expression %d: ",t++);if(!q1.empty()) deal(q1.top());if(q2.top()==1) puts("V");else puts("F");}return 0;
}

转载于:https://www.cnblogs.com/nyist-TC-LYQ/p/7208090.html

POJ 2106-Boolean Expressions,双栈运用类似表达式求值!相关推荐

  1. php表达式求值,PHP实现基于栈的后缀表达式求值功能

    本文实例讲述了PHP实现基于栈的后缀表达式求值功能.分享给大家供大家参考,具体如下: 后缀表达式概述 后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左 ...

  2. 栈实现算术表达式求值

    算术表达式求值 利用栈求解的一个典型的问题是算术表达式求值,例如:"3+4*2-(1+1)#",这样的表达式计算,在计算过程中,不是读到一个运算就立即计算,而是要与后面的运算符进行 ...

  3. 栈的应用——表达式求值(双栈)

    1.表达式求值 中缀表达式是正常的表达式形式, 例如:4.99 * 1.06 + 5.99 + 6.99 * 1.06 后缀表达式是针对中缀表达式而言的,可以理解为:操作符在两个操作数之后. 例如:4 ...

  4. 北京林业大学数据结构实验二 基于栈的算术表达式求值算法

    第1关:基于栈的中缀算术表达式求值 参见课本P75 例3.3 #include <iostream> #include<iomanip>#define MAXSIZE 100 ...

  5. 数据结构课程设计---------用栈来实现表达式求值

    1.需求分析 设计一个程序,演示用算符优先法对算术表达式求值的过程.利用算符优先关系,实现对算术四则混合运算表达式的求值. (1)输入的形式:表达式,例如2*(3+4)      包含的运算符只能有' ...

  6. 基于栈的后缀表达式求值(洛谷P1449题题解,Java语言描述)

    题目要求 P1449题目链接 分析 给出后缀表达式求值,就相当于没了括号,而且很直接. 我们需要使用栈结构来完成任务. Java原装的栈使用了很多synchronized,导致性能不佳,但我们也就将就 ...

  7. 【Java】基于栈的算术表达式求值

    定义异常类 public class ExpressionException extends RuntimeException {private static final long serialVer ...

  8. 栈的应用——表达式求值

    概要 表达式求值问题可以说是一个经典问题.具体思路就是首先把输入的中缀表达式转换为后缀表达式,然后再根据后缀表达式进行计算求值. 中缀表达式转换为后缀表达式 首先我们设定运算符在进栈前与进栈后的优先级 ...

  9. 编程题实训-实验2-基于栈的算术表达式求值算法(北京林业大学)

    第1关:基于栈的中缀算术表达式求值 任务描述 本关任务:输入一个中缀算术表达式,求解表达式的值.运算符包括+.-.*./.(.).=,参加运算的数为double类型且为正数.(要求:直接针对中缀算术表 ...

最新文章

  1. 46岁谷歌创始人佩奇、布林双双卸任,皮查伊接任母公司CEO
  2. vCenter6.0配置二:配置HA群集
  3. 苹果真要开发无线充电外壳 已要求联发科提供芯片样品
  4. ubuntu-14.04.2-desktop-i386.iso:ubuntu-14.04.2-desktop-i386:安装Oracle11gR2
  5. JVM 学习四:类加载之双亲委派机制与沙箱安全机制
  6. 第6课 - 开发中的辅助工具
  7. 大数据DMP画像系统(转载 简介-龙果学院)
  8. Ignite分布式的内存数据库简单应用
  9. 登录邮箱用哪个好,好用的登录邮箱推荐
  10. 线程停止(stop/intrrupt)
  11. Hadoop数据本地化
  12. Blurry Box加密技术使用的7种方法
  13. 2021年美亚杯资格赛解析
  14. 【应届生笔试资料分享二】中国农业银行相关介绍汇总
  15. Goldwasser-Micali 公钥加密系统
  16. spark提交python程序_Spark任务提交(Spark Submit)
  17. ADB:通过 Wi-Fi 连接到Android设备的两种方法
  18. UE4对于对象的剔除
  19. 快手校园招聘工程笔试B卷-搭积木
  20. 笔记本整机性能测试软件,整机性能测试_笔记本评测-中关村在线

热门文章

  1. 【HDU - 2639】Bone Collector II (第K大背包,dp,STLset)
  2. 【Effect CodeForces - 270D】Greenhouse (思维,最长非递减子序列(上升),对偶问题,考虑反面)
  3. 【CF#468 div2 D. 】Peculiar apple-tree(思维)
  4. 详解停车位检测算法 Vision-Based Parking-Slot Detection: A DCNN-Based Approach and a Large-Scale Benchmark
  5. 两组的数据平均值合并_不要进入数据陷进
  6. 黔南民族师范学院计算机与信息学院,黔南民族师范学院
  7. JavaMelody开源系统性能监控软件:
  8. linux mint安装步骤,Linux mint 安装步骤
  9. key_t IPC键和ftok函数详解和剖析
  10. 剑指offer_02