题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237

题目大意:读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

题目分析:

我们可以利用栈来解决这道问题。

首先,对于我们来说,这道题目比较简单,没有用到小括号。

对于遇到小括号的情况,我们可能会用递归来实现“有小括号先求小括号里面的”的效果。

但是因为这里没有,所以我们只需要处理“加减乘除”就可以了,

可以发现,“加减”是一类的;“乘除”是一类的。

所以我们可以这么做:

我们开两个栈:stack1和stack2,stack1用于存放数字,stack2用于存放符号(+或-),

首先,我们把公式中的第一个数字放入stack1中,

接下来我们每次处理一个符号c和一个数字a,

如果c是乘号或者除号,那么我们只需要取出stack1中的栈顶元素b,然后将 a*b 或者 a/b 的结果在放入stack中即可。

如果c是加号或者减号,那么我们要判断一下此时stack1中的元素个数,

如果stack1中只有一个元素,那么我们将a放入stack1中,将c放入stack2中,因为对于a来说,他的下一步运算很有可能是乘除运算,

所以还是需要将此时的a留在栈顶以北接下来的运算的。

如果stack1中有两个元素,而此时的符号是加号或者减号,那就是说,我新加进来的以a开头的部分,最终是要和他前面的这两个stack1中的元素做加减运算的。

那么我们就可以先将stack1中的两个元素先合并了,那么我们假设:

先从stack1中出来的是num1(这个num1是表达式中靠后的元素,因为栈是“后进先出”),

后从stack1中出来的是num2(这个num2是表达式中靠前的元素),

而stack2中取出的元素是c的话,

如果c是+,则我们将num2+num1重新放入stack1中;

如果c是-,则我们将num2-num1重新放入stack1中。

我们按照这样的方式一直进行到遍历完整个表达式。

此时stack1中可能存在一个元素,也可能还存在两个元素,

那么在存在两个元素的情况下,我们可以知道,这两个元素肯定是加减运算的,因为我们不将乘除号放入stack2中,只将加减号放入stack2中。所以我们只需要进行一下上述的过程就可以将stack1中的元素变成一个了。

那么最终的结果就是stack1中剩余的这唯一一个元素。

其他

这道题目有一个要注意的地方就是他是以0为单独一行结尾就算输入结束了。

但是表达式的第一个元素也有可能是0,所以我就是因为没有处理这个导致WA了两次,所以对于输入数据的处理请注意避坑。

代码:

#include <bits/stdc++.h>
using namespace std; stack<double> stk1, stk2;
// stk1用于存放数字,stk2用于存放符号,
// 因为stk2里面的符号只可能是+或-,所以用1表示+,用-1表示- double a;
char c; int main() {
while (~scanf("%lf", &a)) {
// if (a == 0) break;
while (!stk1.empty()) stk1.pop();
while (!stk2.empty()) stk2.pop();
stk1.push(a);
bool eofFlag = true;
while ((c = getchar()) != '\n') {
eofFlag = false;
scanf("%c %lf", &c, &a);
double b;
switch (c) {
case '*':
b = stk1.top();
stk1.pop();
stk1.push(b * a);
break;
case '/':
b = stk1.top();
stk1.pop();
stk1.push(b / a);
break;
default:
if (stk1.size() == 2) { // 其实是==2就行
double num1 = stk1.top();
stk1.pop();
double num2 = stk1.top();
stk1.pop();
double flag = stk2.top();
stk2.pop();
stk1.push(num2 + flag * num1);
}
stk1.push(a);
stk2.push( c == '+' ? 1 : -1 );
break;
}
}
if (eofFlag) { return 0; }
if (stk1.size() == 2) {
double num1 = stk1.top();
stk1.pop();
double num2 = stk1.top();
stk1.pop();
double flag = stk2.top();
stk2.pop();
stk1.push( num2 + flag * num1 );
}
double res = stk1.top();
printf("%.2lf\n", res);
}
return 0;
}

另外,我还碰到一道除了加减乘除还有小括号的题目,这道题目就是递归处理一下,每一个子部分还是不带小括号的,下面是样例代码。

不过下面的样例代码在输入部分是没有空格的,比如下面是一组样例数据:

样例输入:

1.000+2/4=

样例输出:

1.50

实现代码:

#include <bits/stdc++.h>
using namespace std; string finalHandle(string s) {
stringstream ss(s);
double a;
char c;
stack<double> stk1, stk2;
ss >> a;
stk1.push(a);
while (ss >> c) {
if (c == '=') break;
ss >> a;
double b;
switch (c) {
case '*':
b = stk1.top();
stk1.pop();
stk1.push(b * a);
break;
case '/':
b = stk1.top();
stk1.pop();
stk1.push(b / a);
break;
default:
if (stk1.size() == 2) { // 其实是==2就行
double num1 = stk1.top();
stk1.pop();
double num2 = stk1.top();
stk1.pop();
double flag = stk2.top();
stk2.pop();
stk1.push(num2 + flag * num1);
}
stk1.push(a);
stk2.push( c == '+' ? 1 : -1 );
break;
}
}
if (stk1.size() == 2) {
double num1 = stk1.top();
stk1.pop();
double num2 = stk1.top();
stk1.pop();
double flag = stk2.top();
stk2.pop();
stk1.push( num2 + flag * num1 );
}
double res = stk1.top();
stringstream sss;
sss << res;
string resString;
sss >> resString;
return resString;
} string handle(string s) {
// cout << s << endl;
int idx1 = -1, idx2 = -1;
for (int i = 0; i < s.length(); i ++) {
if (s[i] == '(') idx1 = i;
else if (s[i] == ')') {
idx2 = i;
break;
}
}
if (idx1 != -1 && idx2 != -1)
return handle(s.substr(0, idx1) + finalHandle(s.substr(idx1+1, idx2-idx1-1) + '=') + s.substr(idx2+1));
else
return finalHandle(s);
} string s; int main() {
cin >> s;
string resString = handle(s);
stringstream ss(resString);
double res;
ss >> res;
printf("%.2lf\n", res);
// test
// finalHandle(s);
return 0;
}
/*
1+2/3*(1+3)+(3*2+5-(1+8*3-7))
*/

HDU1237 简单计算器 栈的更多相关文章

  1. hdu-1237简单计算器(栈的运用)

    http://acm.hdu.edu.cn/showproblem.php?pid=1237 简单的栈的运用. 首先将数字和运算符分离,分别保存在两个数组中,然后按原来的式子的顺序,首先将第一个数和第 ...

  2. hdu1237 简单计算器[STL 栈]

    目录 题目地址 题干 代码和解释 参考 题目地址 hdu1237 题干 代码和解释 解本题时使用了STL 栈,要记得使用#include<stack>. 解本题时使用了isdigit()函 ...

  3. HDU1237 简单计算器 【栈】+【逆波兰式】

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  4. hiho #1332 : 简单计算器 栈+递归

    #1332 : 简单计算器 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 编写一个程序可以完成基本的带括号的四则运算.其中除法(/)是整除,并且在负数除法时向0取整.( ...

  5. F - 简单计算器(栈)

    F - 简单计算器 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descripti ...

  6. HDU1237 简单计算器 2016-07-24 13:34 193人阅读 评论(0) 收藏

    简单计算器 Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过 ...

  7. HDU 1237 简单计算器 栈

    额,题目是中文的,题意就不用说了= =都看懂喽.写个字符串先把这行计算式存进去,不过不能存一个算一个,因为考虑到乘除法比加减法优先的原则,如果是加号减号就先存着等待计算,如果是乘号除号就直接算出来值就 ...

  8. hdu-1237 简单计算器---中缀表达式转后缀表达式

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 思路 ...

  9. hdu 1237 简单计算器(栈处理)

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

随机推荐

  1. jQuery弹出提示信息自动消失简洁版

    // 在bootstrap中可以,可以使用如下方式实现弹出提示信息自动消失,如果没有使用bootstrap框架,可以自定义样式 //tip是提示信息,type:'success'是成功信息,'dang ...

  2. 安装 selenium 对于python而言属于一个第三方的模块

    针对第三方的模块,如何安装 在dos界面输入python -m pip install 模块名称 安装相关的浏览器以及浏览器的驱动 下载谷歌浏览器的驱动,淘宝镜像 下载后,解压,然后将得到的exe文件 ...

  3. Canvas 总结,到第4章 canvas图形变换

    canvas 必须认识到的大坑 <!-- 重点: 在js/canvas标签中定义的宽和高是画布实际的宽和高. 在样式表中定义的宽和高是画布缩放后的宽和高. 即:把js/canvas实际大小缩放到 ...

  4. LOJ P10131 暗的连锁 题解

    每日一题 day27 打卡 Analysis 对于每条非树边 , 覆盖 x 到 LCA 和 y到 LCA 的边 , 即差分算出每个点和父亲的连边被覆盖了多少次 .被覆盖 0 次的边可以和 m 条非树边 ...

  5. mongoDB sh.status() too many chunks to print

    too many chunks to print, use verbose if you want to force print 想要看到详细的信息则需要执行: mongos> sh.statu ...

  6. Kubernetes 学习3 kubeadm初始化k8s集群

    一.k8s集群 1.k8s整体架构图 2.k8s网络架构图 二.基于kubeadm安装k8s步骤 1.master,nodes:安装kubelet,kubeadm,docker 2.master: k ...

  7. (3)Go运算符

    运算符 Go 语言内置的运算符有: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 算数运算符 运算符 描述 + 相加 - 相减 * 相乘 / 相除 % 求余 注意: ++(自增)和--(自 ...

  8. http2 3

    HTTP 2 推荐阅读:https://segmentfault.com/a/1190000011172823?utm_source=tag-newest 进来支持 HTTP 2 的网站越来愈多了,这 ...

  9. UOJ#220. 【NOI2016】网格 Tarjan

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ220.html 前言 真是一道翔题. 草率题解 -1 的情况很好判,只有两种情况: n * m - c < 2 或者 ...

  10. Java GUI小程序--画板

     画板效果  (以前写在Csdn上的博文,没去水印,Csdn名字同博客园) 布局类: package gary; import java.awt.Color; import java.awt.even ...