表达式求值
时间限制: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
分析:
先了解算术四则运算规则:
(1)先乘除,后加减;
(2)从左算到右;
(3)先小括号内,后括号外。
在运算的每一步中,任意两个相继出现的算符 q1 和 q2 之间的优先关系,至多是下面3种关系之一:
q1 < q2 q1 的优先权低于 q2
q1 = q2 q1 的优先权等于 q2
q1 > q2 q1 的优先权高于 q2
算符间的优先关系:
第一列为q1 第一行为 q2
+ | _ | * | / | ( | ) | # | |
+ | > | > | < | < | < | > | > |
_ | > | > | < | < | < | > | > |
* | > | > | > | > | < | > | > |
/ | > | > | > | > | < | > | > |
( | < | < | < | < | < | = | |
) | > | > | > | > | > | > | |
# | < | < | < | < | < | = |
源程序为:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
// + - × / ( ) # 优先级的比较,100表示不存在该种情况发生
int map[7][7]={
{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,100},
{1,1,1,1,100,1,1},
{-1,-1,-1,-1,-1,100,0}
};
char str[1005],optr[1005];
double opnd[1005];
int cam(char c)
{
switch(c){
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#': return 6;
}
}
double sol(double x,char c,double y)
{
switch(c){
case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': return x/y;
}
}
int z(char c)
{
if('0'<=c && c<='9' || c=='.')
return 1;
if(c==' ') return -1;
return 0;
}
int main()
{
int t1,t2,k;
char ch,zz;
int temp1,temp2;
double a,b;
int t;
scanf("%d",&t);
getchar();
while(t--){
gets(str);
int len=strlen(str);
str[len-1]='#'; //处理的等于号
t1=t2=k=0;
optr[t1++]='#';
ch=str[k++];
while(ch!='#' || optr[t1-1]!='#'){
if(z(ch)==1){ //操作数入栈
opnd[t2++]=atof(&str[k-1]);
while(z(str[k])==1)
k++;
ch=str[k++];
}
else if(z(ch)==-1)
ch=str[k++];
else{
temp1=cam(optr[t1-1]);
temp2=cam(ch);
if(map[temp1][temp2]==-1){ //栈顶元素优先权低
optr[t1++]=ch;
ch=str[k++];
}
else if(map[temp1][temp2]==0){
t1--;
ch=str[k++];
}
else{
zz=optr[--t1];
a=opnd[--t2];
b=opnd[--t2];
opnd[t2++]=sol(b,zz,a);
}
}
}
printf("%.2lf\n",opnd[0]);
}
return 0;
}