表达式求值
时间限制: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
代码:
# include <stdio.h>
# include <math.h>
# include <string.h>
# include <stack>
using namespace std;
char s[1005];
stack<double> dtack;
stack<char> ctack;
int main(void)
{
int n;
scanf("%d", &n);
while (n--)
{
scanf("%s", &s[1]);
int len = strlen(&s[1]);
s[0] = '(';
s[len] = ')';
int i;
for (i = 0; i <= len; i++)
{
if (s[i] == '(')
{
ctack.push(s[i]);
}
else if (s[i] >= '0' && s[i] <= '9')
{
double v = 0.0;
int spot = 0; // 用以记录小数点的位置
while (s[i] >= '0' && s[i] <= '9' || s[i] == '.')
{
if (s[i] == '.')
{
spot = i;
}
else
{
v = v * 10 + (s[i] - '0');
}
i++;
}
i--;
if (spot == 0)
{
dtack.push(v);
}
else
{
dtack.push(v / pow(10, (i - spot)));
}
}
else if (s[i] == '+' || s[i] == '-')
{
while (ctack.top() != '(')
{
double a = dtack.top(); dtack.pop();
double b = dtack.top(); dtack.pop();
double c = 0.0;
switch(ctack.top())
{
case '+' :
c = b + a;
break;
case '-' :
c = b - a;
break;
case '*' :
c = b * a;
break;
case '/' :
c = b / a;
break;
}
dtack.push(c); //把计算的结果压入栈中
ctack.pop();//弹出运算过的运算符
}
ctack.push(s[i]);
}
else if (s[i] == '*' || s[i] == '/')
{
if (ctack.top() == '*')
{
double a = dtack.top(); dtack.pop();
double b = dtack.top(); dtack.pop();
dtack.push(b * a);
ctack.pop();
}
else if (ctack.top() == '/')
{
double a = dtack.top(); dtack.pop();
double b = dtack.top(); dtack.pop();
dtack.push(b / a);
ctack.pop();
}
ctack.push(s[i]);
}
else if (s[i] == ')')
{
while (ctack.top() != '(')
{
double a = dtack.top(); dtack.pop();
double b = dtack.top(); dtack.pop();
double c = 0.0;
switch (ctack.top())
{
case '+' :
c = b + a;
break;
case '-' :
c = b - a;
break;
case '*' :
c = b * a;
break;
case '/' :
c = b / a;
break;
}
dtack.push(c);
ctack.pop();
}
ctack.pop();
}
}
printf("%.2lf\n", dtack.top());
dtack.pop();
}
return 0;
}
典型的进栈和出栈