问题 C: 某计算器的超电磁炮(加减乘除括号表达式求值)

时间:2021-01-17 14:42:30
时间限制: 1 Sec内存限制: 64 MB提交: 510解决: 156
提交状态
题目描述
输入由非负整数、+、-、*、/、(、)组成的计算表达式,计算该表达式的值。

输入
每个输入文件中一组数据。

输入只有一行,不超过200个字符,其中不存在空格。数据保证表达式一定合法,且所有的整数都不小于0、不大于1024。中间结果保证不超过15位有效数位精度。

输出
输出一行,即表达式的值,结果精度保留小数点后2位。

样例输入
3+(12/(2*2+1))
样例输出
5.40
提示

此题是数据结构课本上的原题,可用栈来做(符号有+-*/()#)
首先读取到的是数字,则进数字栈若不是则考虑各个符号的优先顺序(假设#是符号栈的栈底,只有当读取到末尾的#号时才出栈)
当读取符号为+或者-时,只有栈顶是(、#才进栈,其余出栈
当读取符号为*或者/时,只有栈顶是(、#、+、-才进栈,其余出栈
当读取符号为(进栈
当读取符号为)时,除了(都出栈,且遇到(实施的是脱括号操作
当读取符号为#时,除了#都出栈,且遇到#实施的是类似脱括号操作
下面是代码

#include<iostream>
#include<string>
#include<vector>
#include<cctype>
using namespace std;
int compare(char x, char y)
{
if ((x == '#'&&y == '#')||(x == ')' && y == '(')) return 0;//脱括号
if (x == '(' || (string("+-").find(x) < 2 && string("(#").find(y)<2) || (string("*/").find(x) < 2 && string("(+-#").find(y) < 4)) return 1;//进栈
return -1;//出栈

}
int main()
{
vector<char> oper;
vector<double> oped;
string s;
cin >> s;
s.push_back('#');//结尾放个结束符#
int t = 0;
oper.push_back('#');//开头放开始符#
while (!oper.empty())
{
if (isdigit(s[t]))//是数字
{
int te = t;
while (isdigit(s[t]))//知道第t位置不是数字,此时t位置正好是非数字位
t++;
oped.push_back(stod(string(s, te, t - te)));//开始位置到t的前一位置转换了double,
}
else
{
int temp = compare(s[t], oper.back());//判断优先顺序
if (temp == 1) oper.push_back(s[t++]);//进栈
else if (temp == 0) { oper.pop_back();t++; }//脱括号
else//出栈
{
double tt;
switch (oper.back()) {
case '+':tt = oped[oped.size() - 2] + oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
break;
case '-':tt = oped[oped.size() - 2] - oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
break;
case '*':tt = oped[oped.size() - 2] * oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
break;
case '/':tt = oped[oped.size() - 2] / oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
break;
}
oper.pop_back();
}
}
}
printf("%.2f\n", oped.back());//输出结果
}