2304: 表达式求值(1)初级版
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 123 Solved: 53
[ Submit][ Status][ BBS]
Description
ACM队想做一个计算器,但是,他们要做的不仅仅是一计算一个A+B的计算器,他们想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他们来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
Input
第一行输入一个整数n,共有n组测试数据(n<100)。
每组测试数据只有一行,是一个字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。输入保证合法,也不会出现负数。(很简单的表达式求值哦,测试数据很水的)
Output
每组都输出该组运算式的运算结果,输出结果保留两位小数。
Sample Input
21.000+2/4=((1+2)*5+1)/4=
Sample Output
Case #1: 1.50Case #2: 4.00
HINT
Source
代码:
#include<cstdio>
#include<cstring>
#define maxn 10001
//const int maxn=10001;
struct
NumStack
{
double
stack[maxn];
int
top;
} numstack;
struct
OpStack
{
char
stack[maxn];
int
top;
} opstack;
char
rpn[maxn];
int
GetLevel(
char
op)
{
if
(op==
'*'
||op==
'/'
)
return
2;
if
(op==
'+'
||op==
'-'
)
return
1;
return
0;
}
double
Add(
double
a,
double
b)
{
return
a+b;
}
double
Sub(
double
a,
double
b)
{
return
a-b;
}
double
Mul(
double
a,
double
b)
{
return
a*b;
}
double
Div(
double
a,
double
b)
{
return
a/b;
}
double
Caculate(
double
a,
double
b,
char
op)
{
switch
(op)
{
case
'+'
:
return
Add(a,b);
case
'-'
:
return
Sub(a,b);
case
'*'
:
return
Mul(a,b);
case
'/'
:
return
Div(a,b);
}
}
void
GetRpn(
char
*str)
{
int
cou=0;
int
isnum=0;
opstack.top=0;
if
(str[0]==
'-'
)
{
rpn[cou++]=
'0'
;
rpn[cou++]=
'#'
;
}
for
(
int
i=0; i<
strlen
(str); i++)
{
if
(str[i]>=
'0'
&&str[i]<=
'9'
||str[i]==
'.'
)
{
isnum=1;
rpn[cou++]=str[i];
}
else
{
if
(isnum)
{
rpn[cou++]=
'#'
;
isnum=0;
}
if
(str[i]==
'='
)
break
;
else
if
(str[i]==
'('
)
{
if
(str[i+1]==
'-'
)
{
rpn[cou++]=
'0'
;
rpn[cou++]=
'#'
;
}
opstack.stack[opstack.top++]=str[i];
}
else
if
(opstack.top==0)
opstack.stack[opstack.top++]=str[i];
else
if
(str[i]==
')'
)
{
while
(opstack.stack[opstack.top-1]!=
'('
)
rpn[cou++]=opstack.stack[--opstack.top];
opstack.top--;
}
else
if
(GetLevel(str[i])<=GetLevel(opstack.stack[opstack.top-1]))
{
while
(opstack.top>0&&GetLevel(str[i])<=GetLevel(opstack.stack[opstack.top-1]))
rpn[cou++]=opstack.stack[--opstack.top];
opstack.stack[opstack.top++]=str[i];
}
else
opstack.stack[opstack.top++]=str[i];
}
}
while
(opstack.top)
rpn[cou++]=opstack.stack[--opstack.top];
rpn[cou]=
'\0'
;
}
double
GetAns(
char
*str)
{
numstack.top=0;
for
(
int
i=0; i<
strlen
(str); i++)
{
if
(str[i]>=
'0'
&&str[i]<=
'9'
)
{
double
ita=0,now=10;
int
flag=0;
for
(; str[i]!=
'#'
; i++)
{
if
(str[i]==
'.'
)
{
flag=1;
i++;
}
if
(flag==0)
{
ita=ita*10+str[i]-
'0'
;
}
else
{
ita+=(str[i]-
'0'
)/now;
now*=10;
}
}
numstack.stack[numstack.top++]=ita;
}
else
{
double
a=numstack.stack[--numstack.top];
double
b=numstack.stack[--numstack.top];
double
c=Caculate(b,a,str[i]);
//printf("%lf %lf %lf\n",a,b,c);
numstack.stack[numstack.top++]=c;
}
}
return
numstack.stack[--numstack.top];
}
int
main()
{
char
str[1001];
int
czs,i;
scanf
(
"%d"
,&czs);
for
(i=0;i<czs;i++)
{
scanf
(
"%s"
,str);
GetRpn(str);
//printf("%s\n",rpn);
printf
(
"Case #%d: %.2lf\n"
,i+1,GetAns(rpn));
}
return
0;
}