表达式求值
时间限制:3000 ms | 内存限制:65535 KB
难度:4
描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0输出每组都输出该组运算式的运算结果,输出结果保留两位小数。样例输入2
1.000+2/4=
((1+2)*5+1)/4=
样例输出1.50
4.00
来源数据结构课本例题改进上传者张云聪
/*1.将中缀表达式转为后缀表达式,链接https://blog.csdn.net/bbc955625132551/article/details/72784464*/
/*原文链接https://blog.csdn.net/f_zyj/article/details/51509958*/
#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
#include <ctype.h>
#include <stdlib.h>
using namespace std;
int rank(char x)
{
int t;
if(x=='(') t=0;
else if(x=='+'||x=='-') t=1;
else t=2;
return t;
}
bool compare(char a,char b)
{
int x=rank(a),y=rank(b);
if(x>y) return 1;
else return 0;
}
void compute(stack<double> &d,stack<char> &t)
{
double x=d.top();
d.pop();
double y=d.top();
d.pop();
switch(t.top())
{
case '+':d.push(y+x);break;
case '-':d.push(y-x);break;
case '*':d.push(y*x);break;
case '/':d.push(y/x);break;
}
t.pop();
}
void arrange(char x,stack<double> &d,stack<char> &t)
{
if(t.empty()) t.push(x);
else
{
while(!t.empty()&&compare(x,t.top())==0) compute(d,t);
t.push(x);
}
}
int main()
{
int n;
cin>>n;
char s[1001];
stack<char> t;
stack<double> d;
while(n--)
{
cin>>s;
for(int i=0;i<strlen(s);i++)
{
if(isdigit(s[i]))
{
double n = atof(&s[i]);
while(i<strlen(s)&&(isdigit(s[i]) ||s[i]=='.')) i++;
i--;
d.push(n);
}
else
{
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') arrange(s[i],d,t);
else if(s[i]=='(') t.push(s[i]);
else if(s[i]==')')
{
while(t.top()!='(') compute(d,t);
t.pop();
}
else while(t.empty()==0) compute(d,t);
}
}
if(d.size()==1) printf("%.2lf\n",d.top());
d.pop();
}
}