描述
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~9
或者.
就利用一个字符串存起来 - 当遇见的不是数字时代表当前遇到了符号,把存储的字符串变成数字,然后压入数字栈中。然后判断当前遇到了什么符号,如果是加减,那么就直接从符号栈中取出两个数字进行计算,然后把结果压入栈中,如果遇到乘除符号,那么就直接先计算栈中的所有的乘除法,再把当前的符号压入栈中
- 如果遇见右括号,或者等号,就直接计算栈中剩余的符号。
- 最后输出数字栈中的栈顶就是答案
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define inf 0x3f3f3f3f
typedef long long ll;
const int N = 1000 + 20;
stack<char> st_ch;
stack<double> st_num;
void calc1()
{
char ch = st_ch.top();
while (ch != '(')
{
double num1 = st_num.top();
st_num.pop();
double num2 = st_num.top();
st_num.pop();
switch (ch)
{
case '+':
num2 += num1;
break;
case '-':
num2 -= num1;
break;
case '*':
num2 *= num1;
break;
case '/':
num2 /= num1;
break;
}
st_num.push(num2);
st_ch.pop();
ch = st_ch.top();
}
}
void calc2()
{
char ch = st_ch.top();
while (ch == '*' || ch == '/')
{
double num1 = st_num.top();
st_num.pop();
double num2 = st_num.top();
st_num.pop();
switch (ch)
{
case '*':
num2 *= num1;
break;
case '/':
num2 /= num1;
break;
}
st_num.push(num2);
st_ch.pop();
ch = st_ch.top();
}
}
int main()
{
//freopen("in.txt", "r", stdin);
string str;
int t;
cin >> t;
while (t--)
{
cin >> str;
int len = str.size();
st_ch.push('(');
string str_num = "";
for (int i = 0; i < len; i++)
{
if (isdigit(str[i]) || str[i] == '.')
{
str_num += str[i];
continue;
}
if (str_num != "")
{
double num = atof(str_num.c_str());
st_num.push(num);
str_num = "";
}
switch (str[i])
{
case '+':
case '-':
calc1();
st_ch.push(str[i]);
break;
case '*':
case '/':
calc2();
st_ch.push(str[i]);
break;
case '(':
st_ch.push('(');
break;
case ')':
case '=':
calc1();
st_ch.pop();
break;
}
}
printf("%.2lf\n", st_num.top());
st_num.pop();
}
return 0;
}