本片文章主要介绍的表达式求值方法是“算符优先法”。
算符优先法就是根据运算优先关系的规定来实现对表达式的编译或解释执行的。
话不多说直接看详细代码:
#include <iostream>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
typedef char SElemType;
typedef int NElemType;
typedef int Status;
//储存运算符的栈
typedef struct{
char* base;
char* top;
int stackSize;
}SqStack_optr;
string s; //用来储存完整地表达式
//储存操作数的栈
typedef struct{
NElemType *base;
NElemType *top;
int stackSize;
}SqStack_opnd;
//运算符栈的初始化
int InitStackS(SqStack_optr& S)
{
S.base=new SElemType[MAXSIZE];
if(!S.base) return false;
S.top=S.base;
S.stackSize=MAXSIZE;
return OK;
}
//操作数栈的初始化
int InitStackN(SqStack_opnd& S)
{
S.base=new NElemType[MAXSIZE];
if(!S.base) return false;
S.top=S.base;
S.stackSize=MAXSIZE;
return OK;
}
//运算符栈入栈操作
int PushS(SqStack_optr& S,SElemType e)
{
if(S.top-S.base==S.stackSize)
return ERROR;
*S.top++=e;
return OK;
}
//操作数栈入栈操作
int PushN(SqStack_opnd& S,NElemType e)
{
if(S.top-S.base==S.stackSize)
return ERROR;
*S.top++=e;
return OK;
}
//运算符栈出栈操作
int PopS(SqStack_optr& S,SElemType& e)
{
if(S.top==S.base )//栈空了
return ERROR;
e=*--S.top;
return OK;
}
//操作数栈出栈操作
int PopN(SqStack_opnd& S,NElemType& e)
{
if(S.top==S.base )//栈空了
return ERROR;
e=*--S.top;
return OK;
}
//运算符栈取栈顶元素
char GetTopS(SqStack_optr S)
{
char e;
if(S.top==S.base)
return ERROR;
e=*(S.top-1);
return e;
}
//操作数栈取栈顶元素
int GetTopN(SqStack_opnd S)
{
int e;
if(S.top==S.base)
return ERROR;
e=*(S.top-1);
return e;
}
//判断当前字符是否为运算符
int In(SElemType c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':
return 1;
default:
return 0;
}
}
//判断运算符的优先级:t1>t2,opnd出栈,运算后再入栈;否则 t2入栈;t1=t2则去掉括号
char Precede(char t1,char t2)
{
int i,j;
char pre[7][7]={// + - * / ( ) =
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}};
switch(t1){
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;
}
switch(t2){
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;
}
return pre[i][j];
}
int Operate(int a,char theta,int b)
{
int c;
switch(theta)
{
case'+':
c=a+b;
break;
case'-':
c=a-b;
break;
case'*':
c=a*b;
break;
case'/':
c=a/b;
break;
}
return c;
}
//ch是用来储存按字符输入的表达式
int evaluate()
{
SqStack_optr OPTR;
SqStack_opnd OPND;
InitStackS(OPTR);
PushS(OPTR,'=');
InitStackN(OPND);
char ch,theta;
int a,b,t,e;
int now=0;//记录上一个状态是数字还是运算符
char x;
cin>>ch;//读取第一个字符
s+=ch;
while(ch!='='||GetTopS(OPTR)!='=')//判断表达式是否读取完毕
{
if(!In(ch))//判断当前读取的字符是操作数还是运算符
{
if(now==1)
{
PopN(OPND,e);
t=ch-'0';
PushN(OPND,e*10+t);
now=1;
}
else
{
PushN(OPND,ch-'0');
now=1;
}
cin>>ch;
s+=ch;
}
else{
now=0;
switch(Precede(GetTopS(OPTR),ch))//比较ch的与OPTR栈顶元素的优先级
{
case'<':
PushS(OPTR,ch);
cin>>ch; //读取下一位字符并将指针向后偏移一位
s+=ch;
break;
case'>':
PopS(OPTR,theta);
PopN(OPND,b);
PopN(OPND,a);
PushN(OPND,Operate(a,theta,b));
break;
case'=':
PopS(OPTR,x);//去掉运算符栈的左括号
cin>>ch; //读取下一位字符并将指针向后偏移一位
s+=ch;
break;
}
}
}
return GetTopN(OPND);
}
int main()
{
cout<<"请输入表达式以=结束:"<<endl;
int ans=evaluate();
cout<<"表达式:"<<s;
cout<<ans;
return 0;
}