您的位置:首页 > 其它

表达式求值之栈的灵活运用

2013-07-31 16:27 197 查看

表达式求值

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


笔者认为关键点在于算术运算符优先级的比较,在本程序中我们把这个优先级事先存入一个二维表内;


再者就是栈的应用了,关键在于栈结构体的定义与栈基址的分配与赋值


源代码如下:


[code]#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define max 1010
typedef struct{
char *base;
char *top;
}Zhan1;
typedef struct{
double *base1;
double *top1;
}Zhan2;
char a1[max];
char     GXB[10][10]={{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}};
char fu[10]={'+','-','*','/','(',')','#'};
char Youxian(char a,char b){
int t,i,j;
for(t=0;t<7;t++)
if(fu[t]==a){i=t;break;}
for(t=0;t<7;t++)
if(fu[t]==b){j=t;break;}
return GXB[i][j];
}
void InitStack(Zhan1 &Fu,Zhan2 &Shu){
Fu.base=(char*)malloc(max*sizeof(char));
Fu.top=Fu.base;
Shu.base1=(double*)malloc(max*sizeof(double));
Shu.top1=Shu.base1;
}
void Push(Zhan1 &Fu,char c){
*Fu.top++=c;
}
void Push1(Zhan2 &Shu,double t){
*Shu.top1++=t;
}
void Pop(Zhan1 &Fu,char &x){
x=*(--Fu.top);
}
void Pop1(Zhan2 &Shu,double &x){
x=*(--Shu.top1);
}
char Gettop(Zhan1 &Fu){
return *(Fu.top-1);
}
double Gettop1(Zhan2 &Shu){
return *(Shu.top1-1);
}
int In(char c){
int i;
for(i=0;i<strlen(fu);i++)
{
if(c==fu[i])return 1;
}
return 0;
}
double Operate(double a,char e,double b){
double t;
if(e=='+')return a+b;
if(e=='-')return a-b;
if(e=='*')return a*b;
if(e=='/')return a/b;
}
void Maker(char *a1){
int len=strlen(a1);
a1[len-1]='#';
}//Maker
double Calculate(){
int i=0;//跟踪当前字符位序
char c,b1[1010],x,theta;
int j;
double t,a,b;
Zhan1 Fu;Zhan2 Shu;
memset(b1,'\0',sizeof(b1));
InitStack(Fu,Shu);//字符栈初始化
Push(Fu,'#');
c=a1[i++];
while(c!='#'||Gettop(Fu)!='#'){
if(!In(c)){
j=0;
memset(b1,'\0',sizeof(b1));
while(!In(c)){
b1[j++]=c;
c=a1[i++];
}//while
t=atof(b1);
Push1(Shu,atof(b1));//操作数进栈
}//if
else
switch(Youxian(Gettop(Fu),c)){
case'<':   //栈顶元素优先权低
Push(Fu,c);c=a1[i++];
break;
case'=':
Pop(Fu,x);c=a1[i++];
break;
case'>':
Pop(Fu,theta);
Pop1(Shu,b);
Pop1(Shu,a);
Push1(Shu,Operate(a,theta,b));
break;
}//switch
}//while
return Gettop1(Shu);
}//Calculate()
int main()
{
int n;
scanf("%d",&n);
while(n--){
scanf("%s",a1);
Maker(a1);//将输入的字符串去掉"="并在末端加上"#"字符
printf("%.2f\n",Calculate());
}
Zhan1 Fu;Zhan2 Shu;
InitStack(Fu,Shu);//字符栈初始化
Push(Fu,'#');
//system("pause");
return 0;
}

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: