栈的输出_程序设计做题笔记:计算表达式(一):栈
题目要求输入一个四则运算表达式(保证合法,不含空格),输出这个表达式的值。
解决这个问题有两种主要的思路,一种是用栈解决,较为符合人在计算四则运算表达式时的行为,从左向右算过去;另一种思路是递归,把原始的表达式不断分割成小表达式,最终计算出结果。这一次先讨论用栈实现的做法。
试想一下我们自己算四则运算时候的内心活动,就是找到一个符合和他两遍的数字,然后算一下,再把这个“小表达式”当成一个新的数字,和后面的数字、符号进行运算。而栈这种数据结构“先进后出(后进先出)”的特点就比较符合这种思维过程,人总是先算最后看到的那个数,栈弹出的也是栈尾元素。
首先为了之后计算方便,我们需要几个简单的函数,isoperator(char ch)用来判断一个字符是不是操作符,getpriority(char ch)用来获取ch这个操作符的优先级,calculate(char ch, int a, int b)用来对a、b用ch进行计算。
//判断是否为操作符
在获取优先级时,'('的优先级最低,因为我们总是先计算括号内的表达式,最后才考虑到括号,而')'则是与'('成对出现的,不用获取它的优先级。
需要注意的是,在calculate中,因为我们从栈中取出数字的顺序和把数字压入栈的顺序是反的,所以如果先取a,再取b(这样比较符合正常人思维),在进行减法和除法时,就要返回b-a和b/a,因为实际上在表达式中b在a的前面。
然后,我们需要建两个栈,数栈和操作符栈,分别存放操作符和数字。操作符包含+、-、*、/、( 和 )。再定义一些临时变量用来代表从栈中抽出来的元素。
stack
现在就可以开始进行压入栈-去除元素-计算-结果压入栈的循环了。
整体思路是,先进行读取,每次从表达式读入一个字符,如果是数字就压入数栈,如果是加减乘除运算符(不含括号),就进行如下判断:
- 如果操作符栈空,就将其压入操作符栈;
- 否则将新读入的操作符ch与操作符栈栈顶元素c比较优先级,如果ch的优先级高,则压入栈留着以后算;
- 否则就弹出栈顶的操作符进行计算,直到栈顶操作符优先级低于ch,或遇到'(',或栈空。
if
(复制过来代码有点错位了bhys...)
这里在读入数字时有一个小操作就是,如果这个数字不止一位,而我们每次只能读入一位数字,就用一个循环把完整的数读进来(isdigit()用来判断字符是不是数字,是自带的函数,不用自己写)。
现在我们来考虑如果读到右括号')'怎么处理。
如果读到右括号,说明当前的读取告一段落,至少一对括号内的表达式读取完了,就开始先把它算出来:一直弹出操作符栈顶的元素进行计算,直到弹出的是左括号。(这里不用考虑栈空的问题,因为有右括号就一定有与之对应的左括号,出现在左括号之后的数字和操作符肯定也在栈里。)
else
把上面这些所有东西装进一个while循环,循环结束时说明整个表达式已经全部读入了,并进行了一部分的计算。我们要做的就是把剩下的算完。
while
这个while结束之后,说明操作符栈空了,此时数栈还剩下一个数,就是整个表达式的结果。
cout
Finish!
满怀信心提交上去。。。结果是个wrong answer。。。
仔细对比我的输出和标准输出之后,发现了一个巨坑无比的地方。。。就是整个表达式之前可能带一个符号!!!就是这个小小的'-'让人过不了!!!
这算什么事,加一个小小的变量negative判断一下就好啦。
于是在开始读入之前加上如下语句:
bool
输出时再根据negative判断一下:
if
这样再提交,肯定没问题了。
仍旧是wrong answer。。。
继续对比输出之后,发现我低估了数据坑的程度——一对小括号里也可能开头是负号。。。
这下咋整啊。。。再写一个栈吧(名叫subnegative)。每次在'('后面读到一个负号就压入栈,遇到')'时就把栈顶元素弹出判断一下这对小括号内表达式的值要不要取负,然后再把结果压入数栈。
嘿!又是wrong answer。。。
此时我已经不再感觉到惊讶了,毕竟我pass了就算编程网格输是吧hhhh
心平气和地对比出错的那个数据,很快就发现了其中蹊跷:小括号里不光可能以'-'开头,还可能是个'+'在前面。。。谁能想得到呢。。。
不过也好改,读到'('时,如果下一个是'+'就把'+'压入栈,是'-'就把'-'压入栈。读到')'时再判断一下就好了。
啊!终于过了(仰天长啸)
贴上完整代码:
#include
栈的输出_程序设计做题笔记:计算表达式(一):栈相关推荐
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- verilog练习:hdlbits网站上的做题笔记(6)
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- verilog练习:hdlbits网站上的做题笔记(5)
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- verilog练习:hdlbits网站上的做题笔记(7)!强烈推荐!
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- verilog练习:hdlbits网站上的做题笔记(8)
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- python 判断是不是汉字危机阅读答案_汉字危机_现代文阅读题在线测试(附答案)_高三语文_在线做题网...
汉字危机 _ 现代文阅读题在线测试(附答案) _ 高三语文 _ 在线做题网 汉字危机 王小峰 中国的书写交流进入键盘划时代只有十几年, 任何一个初次接触电脑的人通过简单的学 习都能迅速掌握文字输入. ...
- buuctf-MISC篇做题笔记(2)
buuctf-MISC篇做题笔记(2) 第七题:基础破解 先看题目提示,可能也要暴力破解 打开后是RAR文件,需要密码 我是用RARpassword暴力破解,且根据题意已知是四位纯数字密码,设置破解的 ...
- 关于数据库设计的做题笔记——选择题+填空题+大题
✅ 一点整理后的做题笔记- 文章目录 一.选择题和填空题 二.大题 三.写后感 ● 我们用的教材: 一.选择题和填空题 逻辑设计阶段的任务包括设计视图,形成数据库的外模式.( ) A. 对 B. 错 ...
- 栈的输出_算法:栈和队列题目集合(一)
前言 栈和队列是算法的一个基本的知识点之一.这篇文章主要介绍三道有关栈和队列的算法题.因为篇幅所限,只介绍push和pop这两种方法的实现 用栈实现队列 用队列实现栈 循环队列的实现 用栈实现队列 入 ...
最新文章
- 21 window对象常见事件
- python中怎么输出中文-python中使用print输出中文的方法
- php imap配置,php中的自定义IMAP命令
- 近期我们在读的那些优质论文,你不了解下?
- python读取mysql中表内数据_Python读取MySQL表数据的方法介绍
- linux 开机启动脚本
- SpringBoot JPA
- 【读书笔记】.NET本质论第四章-Programming with Type(Part Two)
- Cocos2d BMFont解析
- 【CCCC】L3-011 直捣黄龙 (30分),Dijkstra维护点权,节点数,路径条数等+路径打印
- Linux安全加固 附脚本
- 新概念模拟电路简介及section5笔记
- android微信打不开怎么办,微信打不开怎么回事 微信打不开怎么办
- sfm三维重建源码_多视图几何三维重建实战系列之COLMAP
- 2020计算机校友会大学排名,2020年校友会大学排名:一个世界一流大学,一个中国一流大学...
- 微信美团服务器异常怎么回事,美团行为存在异常怎么解决?美团账号异常怎么回事...
- 6-2 求解一元二次方程实根的函数 (10 分)
- RHadoop实验 – 统计邮箱出现次数
- 不忘初心,砥砺前行——移宇科技助力泸州市内分泌学术年会
- golang 字符串拼接性能比较