原题地址:http://ac.jobdu.com/problem.php?pid=1101
题目描述:
对于一个不存在括号的表达式进行计算
-
输入:
-
存在多种数据,每组数据一行,表达式不存在空格
-
输出:
-
输出结果
-
样例输入:
-
6/2+3+3*4
-
样例输出:
-
18
-
来源:
本题和之前一篇博客《九度OJ 1019简单计算器》几乎一致,但是当时写完1019后再次做这个题,其实还有另外的解法。由于只有四则运算,所以不用拘泥于运算符的优先级,说白了就是乘除法比加减法先算而已,所以换一种思路实现。
依然是从左到右遍历字符串(为输入串加上终结符#),遇到数字就将其加入string类型的numStr中,要保证整个数串都被加入,当遇到运算符时,将该string转为数字后压入数字串,这时候我们看看符号栈,如果符号栈为空则压入符号(说明数字栈里只有一个数字);如果非空且栈顶运算符是*和/的话就立刻取出两个操作数做运算,能保证乘除法比加减法先算。这样的话不断处理完了乘除法,最后需要做的只是做整个数字栈的加减法。
AC代码如下:
#include <iostream>
#include <stack>
#include <string>
#include <cstdlib>
#include <cctype>
using namespace std;
int main()
{
string data;
string numStr = "";
while (cin >> data)
{
data += '#'; //表达式末尾添加结束符#
stack<double> num; //存放操作数
stack<char> op; //存放运算符
for (int i = 0; data[i]; ++i)
{
if(isdigit(data[i])) //取到整个数串
numStr += data[i];
else
{
num.push(atoi(numStr.c_str())); //数字入栈
numStr = "";
if (!op.empty()) //只取出乘法或除法运算符
{
char c = op.top();
if (c == '*') //处理乘法
{
op.pop();
int b = num.top();num.pop();
int a = num.top();num.pop();
num.push(a*b);
}
if (c == '/') //处理除法
{
op.pop();
int b = num.top();num.pop();
int a = num.top();num.pop();
num.push(a/b);
}
}
if(data[i] != '#') op.push(data[i]); //当前运算符入栈
}
}
while(!op.empty()) //处理剩余的加减法
{
char c = op.top();
if (c == '+')
{
op.pop();
int b = num.top();num.pop();
int a = num.top();num.pop();
num.push(a+b);
}
if (c == '-')
{
op.pop();
int b = num.top();num.pop();
int a = num.top();num.pop();
num.push(a-b);
}
}
cout << num.top() << endl;
}
return 0;
}
内存占用:1524Kb 耗时:10ms
算法复杂度:O(n)