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。未正确判断好括号关系。

  1. const int N=1e6+10;
  2. stack<char>q1;
  3. stack<int>q2;
  4. char s[150];
  5. void ch(char c)
  6. {
  7. if(c=='!')
  8. {
  9. int x1=q2.top();q2.pop();
  10. x1=!x1;
  11. q2.push(x1);
  12. }
  13. else if(c=='&')
  14. {
  15. int x1=q2.top();q2.pop();
  16. int x2=q2.top();q2.pop();
  17. q2.push(x1&x2);
  18. }
  19. else if(c=='|')
  20. {
  21. int x1=q2.top(); q2.pop();
  22. int x2=q2.top(); q2.pop();
  23. q2.push(x1|x2);
  24. }
  25. q1.pop();
  26. }
  27. int main()
  28. {
  29. int t=1;
  30. char c;
  31. while(1)
  32. {
  33. c=getchar();
  34. if(c==' ') continue;
  35. if(c=='\n'||c==EOF)
  36. {
  37. while(!q1.empty())
  38. {
  39. if(q1.top()!='(') ch(q1.top());
  40. else q1.pop();
  41. }
  42. printf("Expression %d: ",t++);
  43. if(q2.top()==1) puts("V");
  44. else puts("F");
  45. while(!q1.empty()) q1.pop();
  46. while(!q2.empty()) q2.pop();
  47. if(c==EOF) break;
  48. else continue;
  49. }
  50. if(c==')')
  51. {
  52. while(!q1.empty()&&q1.top()!='(') ch(q1.top());
  53. q1.pop();//本意是删去‘(’,但应该判断是否为空且栈顶是否为‘(’
  54. }
  55. else
  56. {
  57. if(c!='V'&&c!='F') q1.push(c);
  58. else
  59. {
  60. if(c=='V') q2.push(1);
  61. else q2.push(0);
  62. while(!q1.empty())//应该判断‘(’截止
  63. {
  64. if(q1.top()!='!'&&q1.top()!='&') break;//‘!’和'&'优先
  65. ch(q1.top());
  66. }
  67. }
  68. }
  69. }
  70. return 0;
  71. }

代码二:AC。

  1. const int N=1e6+10;
  2. stack<char>q1;
  3. stack<int>q2;
  4. char s[N];
  5. void ch(char c)
  6. {
  7. if(c=='!')
  8. {
  9. int x=q2.top();
  10. q2.pop();
  11. q2.push(!x);
  12. }
  13. else if(c=='&')
  14. {
  15. int x1=q2.top();
  16. q2.pop();
  17. int x2=q2.top();
  18. q2.pop();
  19. q2.push(x1&x2);
  20. }
  21. else if(c=='|')
  22. {
  23. int x1=q2.top();
  24. q2.pop();
  25. int x2=q2.top();
  26. q2.pop();
  27. q2.push(x1|x2);
  28. }
  29. q1.pop();
  30. }
  31. int main()
  32. {
  33. int t=1;
  34. while(gets(s))
  35. {
  36. while(!q1.empty()) q1.pop();
  37. while(!q2.empty()) q2.pop();
  38. int len=strlen(s);
  39. for(int i=0; i<len; i++)
  40. {
  41. if(s[i]==' ') continue;
  42. if(s[i]==')')
  43. {
  44. while(!q1.empty()&&q1.top()!='(') ch(q1.top());
  45. if(!q1.empty()&&q1.top()=='(') q1.pop();//删去左括号
  46. }
  47. else
  48. {
  49. if(s[i]!='F'&&s[i]!='V') q1.push(s[i]);
  50. else
  51. {
  52. if(s[i]=='F') q2.push(0);
  53. else q2.push(1);
  54. while(!q1.empty()&&q1.top()!='(')
  55. {
  56. if(q1.top()!='&'&&q1.top()!='!') break;
  57. ch(q1.top());
  58. }
  59. if(!q1.empty()&&q1.top()=='(') q1.pop();
  60. }
  61. }
  62. }
  63. printf("Expression %d: ",t++);
  64. while(!q1.empty()) ch(q1.top());
  65. if(q2.top()==1) puts("V");
  66. else puts("F");
  67. }
  68. return 0;
  69. }

代码三:hacked   V|F&F

  1. const int N=1e3+10;
  2. stack<char>q1;
  3. stack<int>q2;
  4. char s[N];
  5. void deal(char tmp)
  6. {
  7. if(tmp==')') q1.pop();
  8. else
  9. {
  10. if(tmp=='V') q2.push(1);
  11. else q2.push(0);
  12. }
  13. while(!q1.empty()&&q1.top()!='(')
  14. {
  15. char c=q1.top();
  16. q1.pop();
  17. if(c=='!'&&!q2.empty())
  18. {
  19. int x=q2.top();
  20. q2.pop();
  21. q2.push(!x);
  22. }
  23. else if(c=='&'&&q2.size()>1)
  24. {
  25. int x1=q2.top();
  26. q2.pop();
  27. int x2=q2.top();
  28. q2.pop();
  29. q2.push(x1&x2);
  30. }
  31. else if(c=='|'&&q2.size()>1)
  32. {
  33. int x1=q2.top();
  34. q2.pop();
  35. int x2=q2.top();
  36. q2.pop();
  37. q2.push(x1|x2);
  38. }
  39. }
  40. }
  41. int main()
  42. {
  43. int t=1;
  44. while(gets(s))
  45. {
  46. while(!q1.empty()) q1.pop();
  47. while(!q2.empty()) q2.pop();
  48. int len=strlen(s);
  49. for(int i=0; i<len; i++)
  50. {
  51. if(s[i]==' ') continue;
  52. if(s[i]=='F'||s[i]=='V'||s[i]==')') deal(s[i]);
  53. else q1.push(s[i]);
  54. }
  55. printf("Expression %d: ",t++);
  56. if(!q1.empty()) deal(q1.top());
  57. if(q2.top()==1) puts("V");
  58. else puts("F");
  59. }
  60. return 0;
  61. }

POJ 2106-Boolean Expressions,双栈运用类似表达式求值!的更多相关文章

  1. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  2. POJ 2106 Boolean Expressions

    总时间限制: 1000ms  内存限制: 65536kB 描述 The objective of the program you are going to produce is to evaluate ...

  3. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

  4. [poj 2106] Boolean Expressions 递归

    Description The objective of the program you are going to produce is to evaluate boolean expressions ...

  5. POJ 2106 Boolean Expressions (布尔表达式求值)

    题意:关于!,&,| 的运算,表达式中V代表true,F代表false. 思路:见代码吧,很详细了. 要注意 !!!F,!(...) 的情况. #include <iostream> ...

  6. (栈的应用5.2.2)POJ 2106 Boolean Expressions(表达式求值)

    /* * POJ_2106.cpp * * Created on: 2013年10月30日 * Author: Administrator */ #include <iostream> # ...

  7. poj 2106 Boolean Expressions 课本代码

    #include<cstdio> const int maxn=100 +10; int val[maxn],vtop; int op[maxn],otop; void insert(in ...

  8. Dijkstra的双栈算术表达式求值算法

    这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...

  9. 算法手记(2)Dijkstra双栈算术表达式求值算法

    这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...

随机推荐

  1. 前端之CSS列表及背景类属性

    一.列表类属性: 1.列表符号样式: list-style-type:disc(实心圆)|circle(空心圆)|square(实心方块)|decimal(数字)|none(去掉列表符号样式); 2. ...

  2. git与GitHub(一)

    相信,很多初入前端者都会对git以及GitHub不太了解,而我当时也经历过各种面试大关,也都会问:你了解git和GitHub吗?那么今天先来说一说git. 那么什么是git? (以下转载自廖雪峰老师的 ...

  3. 关于IE兼容的问题

    以下内容,均来自不同的网站,非本人原创,只是收集一下放在一起! =============================== [一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 ...

  4. JavaScript的语音识别

    有没有想过给您的网站增添语音识别的功能?比如您的用户不用点鼠标,仅仅通过电脑或者手机的麦克风发布命令,比如"下拉到页面底部",或者"跳转到下一页",您的网站就会 ...

  5. wxwidgets编译及环境配置

    wxwidgets编译及环境配置 安装步骤: 到www.CodeBlocks.org下载并安装CodeBlocks,最好下载MinGW版本的,可以省掉安装和配置GCC的麻烦. 到www.wxWidge ...

  6. UVA - 1279 Asteroid Rangers (动点的最小生成树)

    题意,有n个匀速动点,求最小生成树的改变次数. 一句话总结:动态问题的一般做法是先求出一个静态的解,然后求出解发生改变的事件,事件按照时间排序,依次处理. 先求出最开始的最小生成树(MST),当MST ...

  7. 补题—Codeforces Round #346 (Div. 2) _智商欠费系列

    这次的题目相对容易 但是智商依旧不够用 原因有三点 1.英文水平堪忧 2 逻辑不严密 3 细节掌握不够好 传送门 http://codeforces.com/contest/659 A 题目大意 圆环 ...

  8. URL URI URN的区别

    下面这张图可以完美的解释他们三者之间的关系 URI包含URL和URN Uniform Resource Identifier :统一资源标志符,用于标识某一互联网资源 Uniform Resoutce ...

  9. No-11.变量进阶

    变量进阶 目标 变量的引用 可变和不可变类型 局部变量和全局变量 01. 变量的引用 变量 和 数据 都是保存在 内存 中的 在 Python 中 函数 的 参数传递 以及 返回值 都是靠 引用 传递 ...

  10. css3中animation属性animation-timing-function知识点以及其属性值steps()

    在animation中最重要的其实就是时间函数(animation-timing-function)这个属性,他决定了你的动画将以什么样的速度执行,所以最关键的属性值也就是cubic-bezier(n ...