NYOJ 35 表达式求值 (中缀表达式 小数 带括号)

表达式求值

时间限制: 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

AC代码:

#include
#include
#include
#include
using namespace std;
int pre(char c)
{
if(c=='=') return 0;
else if(c=='+'||c=='-') return 1;
else if(c=='*'||c=='/') return 2;
return 0;
}
void answer(stack &num,stack &op)
{
double b=num.top();
num.pop();
double a=num.top();
num.pop();
switch(op.top())
{
case '+':num.push(a+b);break;
case '-':num.push(a-b);break;
case '*':num.push(a*b);break;
case '/':num.push(a/b);break;
}
op.pop();
}
int main()
{
stack num;//存储数字 
stack op;//存储操作符 
char s[1005];
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
for(int i=0;s[i]!='\0';i++)
{
if(isdigit(s[i]))//判断这个字符是不是数字 
{
double temp=atof(&s[i]);
//将这串字符转化成对应的数字,直到遇到不是数字或小数点为止 
num.push(temp);
while(isdigit(s[i])||s[i]=='.')
i++;
i--;
}
else//这个字符是操作符 
{
if(s[i]=='(') op.push(s[i]);//是左括号 
else if(s[i]==')')//是右括号 
{
while(op.top()!='(')
answer(num,op);
op.pop();//把( 移出栈 
}
//是优先级大于栈顶的操作符,或栈为空,直接进栈 
else if(op.empty()||pre(s[i])>pre(op.top()))
op.push(s[i]);
//是优先级不大于栈顶的操作符,且栈不空,先进行运算操作
//直到不符合上述条件为止,然后该操作符进栈 
else if(!op.empty()&&pre(s[i])<=pre(op.top()))
{
while(!op.empty()&&pre(s[i])<=pre(op.top()))
answer(num,op);
op.push(s[i]);//将优先级大于它的操作做完再让它进栈 
}
}
}
printf("%.2lf\n",num.top());//留在数字栈内的栈顶就是结果 
num.pop();//结果出栈 
op.pop();//等号出栈 
//以上两部清空了栈 
}
return 0; 
}

你可能感兴趣的:(NYOJ 35 表达式求值 (中缀表达式 小数 带括号))