ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
比如输入:“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
这题以前做过一次,这次直接上代码吧,可能现在写要费些时间了,干脆把代码写注释吧
//nyoj 35
#include<iostream>
#include<cstring>
#include<sstream>
#include<string>
#include<cstring>
#include<iomanip>
#include<stack>
using namespace std;
char mid[1008],post[1008]; //前缀,后缀表达式
char compare(char c,char d) //比较优先级
{
switch(c)
{
case '+':
case '-':if(d=='+'||d=='-'||d==')'||d=='=') return '>';else return '<';break;
case '*':
case '/':if(d=='+'||d=='-'||d=='*'||d=='/'||d==')'||d=='=') return '>';else return '<';break;
case '(':if(d==')') return '='; if(d=='=') return '>';else return '<';break;
case ')':if(d=='(') return '='; return '>';break;
case '=':if(d=='=') return '='; else return '<';break;
}
}
//字符串转换为double
double To(char a[]) //sstream头文件中的函数
{
stringstream oss;
oss<<a;
double result;
oss>>result;
return result;
}
bool ischar(char c) //判断是否为操作符
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='=') return true;
return false;
}
void change(char mid[],char post[]) //前缀表达式变后缀表达式
{
stack<char> s1; //存入栈中
char a[1000];
s1.push('='); //压入操作符 =
int i=0,m=-1,l=strlen(mid);
while(i<l)
{
char ch;
if((mid[i]>='0'&&mid[i]<='9')||(mid[i]=='.')) //数字及小数点一起压入后缀表达式中
{
post[++m]=mid[i];
i++;
}
else
{
post[++m]=' '; //加入一个空格,方便转换数据
if(compare(s1.top(),mid[i])=='<') { s1.push(mid[i]);i++;} //栈外符号优先级大于栈内,压入
else if(compare(s1.top(),mid[i])=='>') { ch=s1.top();s1.pop();post[++m]=ch;} //退栈,并放入后缀表达式中
else if(compare(s1.top(),mid[i])=='=') { s1.pop();++i;} //退栈
}
}
}
double Operator(double a,char b,double c) //运算
{
if(b=='+') return a+c;
if(b=='-') return a-c;
if(b=='*') return a*c;
if(b=='/') return a/c;
}
double run(char post[]) //后缀表达式计算
{
int l=strlen(post);
int i=0,flag=0;
stack<double> str; //有栈来存储结果
char q[20]; //用来转换 数据
memset(q,0,20);
int j=-1;
double result,x,y;
while(i<l)
{
if(post[i]>='0'&&post[i]<='9'||post[i]=='.')
{
q[++j]=post[i];
flag=1; //若为含有小数的数据,直到为空格或者操作符才进行转换
++i;
continue;
}
else
{
if(flag==1) {
result=To(q);flag=0;j=-1;str.push(result); //转换数据 压入栈内
memset(q,0,20);
}
if(post[i]==' ') i++; //空格为无效数据,只是方便转换
if(ischar(post[i])) //操作符则进行运算,把结果压入栈内
{
x=str.top();str.pop(); y=str.top(); str.pop();
str.push(Operator(y,post[i],x));++i;
}
}
}
return str.top(); //返回结果
}
int main()
{
int n;
cin>>n;
while(n--)
{
cin>>mid;
change(mid,post);
cout<<setiosflags(ios::fixed)<<setprecision(2)<<run(post)<<endl;
memset(post,0,1008);
}
// system("pause");
return 0;
}