表达式求值
时间限制:
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
-
第一行输入一个整数n,共有n组测试数据(n<10)。
用两个栈实现,一个存运算符一个存结果,如果遇到数字则压入存结果的栈,如果是左括号,则直接压入运算符的栈,如果是运算符,则比较一下如果存运算符的栈栈定元素的优先级高于或者等于当前运算符的优先级,则弹出两个数字和一个运算符进行运算,结果再存到结果的栈里,直到栈定的运算符低于当前读入的运算符或者遇到 ( ,则把当前的运算符压栈,需要注意的是)和=的处理方式和+ - 一样,但不同的是 + - 在弹栈完成后会把当前的运算符 + 或者- 压栈,而 )和=则不会压栈,只会抵消一个(,所以有一个小技巧就是在运算前就压入一个(来抵消最后=的压入,否则很容易在=处理时栈空而报错
#include<stdio.h>
#include<stack>
#include<stdlib.h>
using namespace std;
stack<double> stack_num;
stack<char> stack_ch;
char str[1003];
char number[100];
void calculate_1()
{
char ch;
double num1, num2;
ch = stack_ch.top();
while(ch != '(')
{
num1 = stack_num.top();
stack_num.pop();
num2 = stack_num.top();
stack_num.pop();
switch(ch)
{
case '*':
num2 *= num1;
break;
case '/':
num2/= num1;
break;
case '+':
num2 += num1;
break;
case '-':
num2 -= num1;
break;
}
stack_num.push(num2);
stack_ch.pop();
ch = stack_ch.top();
}
}
void calculate_2()
{
char ch;
double num1, num2;
ch = stack_ch.top();
while(ch == '*' || ch == '/')
{
num1 = stack_num.top();
stack_num.pop();
num2 = stack_num.top();
stack_num.pop();
switch(ch)
{
case '*':
num2 *= num1;
break;
case '/':
num2/= num1;
break;
}
stack_num.push(num2);
stack_ch.pop();
ch = stack_ch.top();
}
}
int main()
{
int num;
int k;
double n;
scanf("%d", &num);
getchar();
while(num--)
{
k = 0;
gets(str);
stack_ch.push('(');
int i;
for(i = 0; str[i];i++)
{
if(str[i] >= '0' && str[i] <= '9' || str[i] == '.')
{
number[k++] = str[i];
continue;
}
number[k] = 0;
if(number[0] != 0)
{
n = atof(number);
number[0] = 0;
stack_num.push(n);
}
k = 0;
switch(str[i])
{
case '+':
calculate_1();
stack_ch.push('+');
break;
case '-':
calculate_1();
stack_ch.push('-');
break;
case '*':
case '/':
calculate_2();
case '(':
stack_ch.push(str[i]);
break;
case ')':
case '=':
calculate_1();
stack_ch.pop();
break;
}
}
printf("%.2lf\n", stack_num.top());
stack_num.pop();
}
return 0;
}