九度OJ 1101 表达式求值(栈的应用)
-
对于一个不存在括号的表达式进行计算
原题地址: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)