栈的应用之一,表达式求值,严慧敏书上给的例子是只有1位数的输入,这里稍微改下,处理下多位数的+、-、*、/。
表达式要求输入合法,且除数要能整除,不然就int掉,算出来错了,主要就是书中优先级表的应用。
省去那些STATUS的返回,什么ERROR OK OVERFLOW 的。
完整代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define InitStackSize 100
#define Increase 100
typedef struct SqcharStack
{
char *base,*top;
int stacksize;
}SqcharStack;
typedef struct SqintStack
{
int *base,*top;
int stacksize;
}SqintStack;
void InitcharStack(SqcharStack &s)
{
s.base=s.top=(char*)malloc(InitStackSize*sizeof(char));
s.stacksize=InitStackSize;
}
void InitintStack(SqintStack &s)
{
s.base=s.top=(int*)malloc(InitStackSize*sizeof(int));
s.stacksize=InitStackSize;
}
void PushcharStack(SqcharStack &s,char key) //字符栈
{
if(s.top-s.base>=s.stacksize)
{
s.base=(char*)realloc(s.base,(s.stacksize+Increase)*sizeof(char));
s.top=s.base+s.stacksize;
s.stacksize+=Increase;
}
*s.top=key;
s.top++;
}
void PushintStack(SqintStack &s,int key) //数字栈
{
if(s.top-s.base>=s.stacksize)
{
s.base=(int*)realloc(s.base,(Increase+s.stacksize)*sizeof(int));
s.top=s.base+s.stacksize;
s.stacksize+=Increase;
}
*s.top=key;
s.top++;
}
char GetcharStackTop(SqcharStack S)
{
char e;
e=*--S.top;
return e;
}
int GetintStackTop(SqintStack S)
{
int e;
e=*--S.top;
return e;
}
int In(char a,char sym[])
{
int i;
for(i=0;i<7;i++)
if(sym[i]==a) return 1;
return 0;
}
void PopcharStack(SqcharStack &s)
{
s.top--;
}
void PopintStack(SqintStack &s)
{
s.top--;
}
char Precede(char a,char b,char pr[][10]) //判断优先级
{
int i,j;
switch(a)
{
case '+':i=0;break;
case '-':i=1;break;
case '*':i=2;break;
case '/':i=3;break;
case '(':i=4;break;
case ')':i=5;break;
case '=':i=6;break;
default:break;
}
switch(b)
{
case '+':j=0;break;
case '-':j=1;break;
case '*':j=2;break;
case '/':j=3;break;
case '(':j=4;break;
case ')':j=5;break;
case '=':j=6;break;
default:break;
}
return pr[i][j];
}
int Operate(int a,int b,char ch)
{
switch(ch)
{
case '+':return b+a;break;
case '-':return b-a;break;
case '*':return b*a;break;
case '/':return b/a;break;
default:break;
}
}
int main()
{
SqcharStack OPTR;
SqintStack OPND;
char str[101];
int i,k,j,byt,num,temp,len;
int a,b;
char theta;
char pre[][10]={
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}}; //优先级表
char OP[]={'+','-','*','/','(',')','='}; //操作符集合
InitcharStack(OPTR);
InitintStack(OPND);
memset(str,'\0',sizeof(str));
while(gets(str))
{
PushcharStack(OPTR,'=');
len=strlen(str);
i=0;
while(i<len)
{
if(str[i]==' ')
{
i++;
continue;
}
if(!In(str[i],OP)) //如果不是操作符,读入数字
{
SqcharStack Num;
InitcharStack(Num);
byt=0; //数字位数
//读入数字字符
for(j=i;!In(str[j],OP) && str[j]!=' ' && str[j]!='\0' && str[j]!='=';j++)
{
PushcharStack(Num,str[j]);
byt++;
}
num=0;//生成数字
temp=1;
while(byt--)
{
k=(GetcharStackTop(Num)-'0');
num+=temp*k;
temp*=10;
PopcharStack(Num);
}
PushintStack(OPND,num);
//while 生成数字
i=j; //i位置跳过数字
}//if 是数字
else//操作符
{
switch(Precede(GetcharStackTop(OPTR),str[i],pre))
{
case '<':PushcharStack(OPTR,str[i]);i++;break; //栈顶元素优先权低
case '=':PopcharStack(OPTR);i++;break;//脱括号
case '>':
theta=GetcharStackTop(OPTR); //取得栈中运算符
PopcharStack(OPTR);
a=GetintStackTop(OPND);
PopintStack(OPND);
b=GetintStackTop(OPND);
PopintStack(OPND);
PushintStack(OPND,Operate(a,b,theta)); //这里注意a,b顺序,反了的话减和除运算就错了
break;
}
}
}//while( || )
printf("The result is:%d\n",GetintStackTop(OPND));
}
return 0;
}
/*
123+456=
4+5*6-10=
(2+8)*6/5=
100/2/2/5=
*/