/*表达式求值
时间限制: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*/
//运用浮点数的读取。
<span style="font-size:18px;">#include<stdio.h>
#include<string.h>
#include<stack>
#include<algorithm>
using namespace std;
//**判断算术符的优先级**//
char precede(char a,char b)
{
if(a=='+'||a=='-')
{
if(b=='+'||b=='-'||b==')'||b=='=') return '>';
else return '<';
}
if(a=='*'||a=='/')
{
if(b=='(') return '<';
else return '>';
}
if(a==')')
{
return '>';
}
if(a=='('||a=='=')
{
if(a=='('&&b==')'||a=='='&&b=='=') return '=';
else return '<';
}
}
//**算术符的运算**//
double operate(double num1,char ch,double num2)
{
double sum;
if(ch=='+')
{
sum=num1+num2;
}
if(ch=='-')
{
sum=num1-num2;
}
if(ch=='*')
{
sum=num1*num2;
}
if(ch=='/')
{
sum=num1/num2;
}
return sum;
}
int main()
{
int ncases,i,k,len,flag;
double x,y;
char c,str[1001],a[1001];
//**建立两个栈,optr储存运算符,opnd存储double字符串(数字字符)**//
stack<char>optr;
stack<double>opnd;
optr.push('=');//**将起始'='作为栈底元素**//
scanf("%d",&ncases);
while(ncases--)
{
memset(str,0,sizeof(str));
memset(a,0,sizeof(a));
flag=0;k=0;
scanf("%s",str);
len=strlen(str);
for(i=0;i<=len-1;)
{
if(str[i]=='='&&optr.top()=='=')//**如果栈顶跟读取的‘=’相同,表示表达式求值完毕**//
{
break;
}
if((str[i]>='0'&&str[i]<='9')||str[i]=='.')//**读取浮点数读取,悲剧啊**//
{
flag=1;//**flag标记是否读取完这一串数字(浮点数)**//
a[k++]=str[i];
i++;
continue;
}
if(flag==1)
{
a[k]='\0';
opnd.push(atof(a));//**atof表示将字符串转化为浮点数(double型),atoi是转化为整型(int型)
flag=0;
k=0;
}
switch(precede(optr.top(),str[i]))
{
case '<'://**栈顶元素优先权低**//
optr.push(str[i]);
i++;
break;
case '='://**脱括号**//
optr.pop();
i++;
break;
case '>': //**退栈并讲运算结果入栈**//
c=optr.top();
optr.pop();
x=opnd.top();
opnd.pop();
y=opnd.top();
opnd.pop();
opnd.push(operate(y,c,x));
break;
}
}
printf("%.2lf\n",opnd.top());
opnd.pop();
}
return 0;
} </span>