#include<bits/stdc++.h>
using namespace std;
include<stdlib.h> //exit()的头文件
#define ERROR -1
#define OK 1
#define TRUE 1
#define FALSE 0
typedef char SElemType;
typedef struct StackNode{
SElemType data; //栈底指针
struct StackNode *next; //栈顶指针
}StackNode,*LinkStack;
typedef int Status;
//初始化
//定义一个栈num,存储数字
Status InitStack(LinkStack &S){
//构造一个空栈num,栈顶指针置空
S = NULL;
return OK;
}
//入栈
Status Push(LinkStack &S,SElemType e){
LinkStack p;
p=new StackNode; //形成新结点
p->data = e; //将新结点的数据域置为e
p->next = S; //将新结点插入栈顶
S=p; //修改栈顶指针为p
return OK;
}
//出栈
Status Pop(LinkStack &S,SElemType &e){
LinkStack p;
//删除S的栈顶元素,用e返回其值
if(S==NULL) return ERROR; //栈空
e=S->data; //将栈顶元素赋给e
p=S; //用p临时保存栈顶元素空间,以备释放
S=S->next; //修改栈顶指针
delete p; //释放原栈顶元素的空间
return OK;
}
//取栈顶元素
SElemType GetTop(LinkStack S){
//返回S的栈顶元素,不修改栈顶指针
if(S!=NULL)
return S->data;
}
//判断是否为运算符函数
Status In(SElemType c){
//判断c是否为运算符
switch(c){
case'+':
return TRUE;
break;
case'-':
return TRUE;
break;
case'*':
return TRUE;
break;
case'/':
return TRUE;
break;
case'(':
return TRUE;
break;
case')':
return TRUE;
break;
case'#':
return TRUE;
break;
default:
return FALSE;
}
}
//判断运算符的优先级
SElemType Precede(SElemType t1,SElemType t2){
SElemType f;
switch(t2){ //t1:栈顶运算符 t2:读取到的运算符
case'+':if(t1=='('||t1=='#'){ //确定t2,在t2确定的条件下改变t1来进行讨论
f='<';
}
else{
f='>';
}
break;
case'-':if(t1=='('||t1=='#'){
f='<';
}
else{
f='>';
}
break;
case'*':if(t1=='*'||t1=='/'||t1==')'){
f='>';
}
else{
f='<';
}
break;
case'/':if(t1=='*'||t1=='/'||t1==')'){
f='>';
}
else{
f='<';
}
break;
case'(':if(t1==')'){
f='=';
}
else{
f='<';
}
break;
case')':if(t1=='('){
f='=';
}
else{
f='>';
}
break;
case'#':if(t1=='#'){
f='=';
}
else{
f='>';
}
break;
default:printf("ERROR");
}
return f;
}
//进行运算操作
SElemType Operate(SElemType a,SElemType theta,SElemType b){
SElemType c;
a=a-48;
b=b-48;
switch(theta) //theta代表运算符
{
case'+':
c=a+b+48;
break;
case'-':
c=a-b+48;
break;
case'*':
c=a*b+48;
break;
case'/':
c=a/b+48;
break;
}
return c; //将过程运算结果定义为c
}
//根据运算关系进行出入栈操作
char EvaluateExpression(){
LinkStack OPND,OPTR; //初始化两个栈,一个叫OPND,一个叫OPTR
InitStack(OPND); //OPND负责存储操作数字
InitStack(OPTR); //OPTR负责存储操作符
/*
a,b,c,theta:Operate()函数中的形参,在此为实参
ch:输入的操作数或操作符
x:
*/
char a,b,theta,ch,x,c; //定义相关的变量,theta与c表示Operate中的操作符与运算结果
Push(OPTR,'#'); //将表达式起始符"#"
cin>>ch;
while(ch!='#'||GetTop(OPTR)!='#') //表达式没有扫描完毕或OPTR的栈顶元素不为"#"
{
if(!In(ch)){Push(OPND,ch);cin>>ch; //ch不是运算符则进OPND栈
}
else
switch(Precede(GetTop(OPTR),ch)){ //比较OPTR的栈顶元素和ch的优先级
case'<':
Push(OPTR,ch); //当前字符ch压入OPTR栈,读入下一字符ch
cin>>ch;
break;
case'>':
Pop(OPTR,theta); //弹出OPTR栈顶的运算符
Pop(OPND,b); //弹出OPND栈顶的两个运算数
Pop(OPND,a);
//将运算结果压入OPND栈,在此需要调用Operate函数,所以应该传参数(实参)进去
Push(OPND,Operate(a,theta,b));
break;
case'=': //OPTR的栈顶元素是"("且ch是")"
Pop(OPTR,x); //弹出OPTR栈顶的"(",读入下一字符ch
cin>>ch;
break;
} //switch
} //while
return GetTop(OPND); //OPND栈顶元素即为表达式的求值结果
}
int main(){
char r; //将结果定义为r
cout<<"请输入一个算数表达式(以字符'#'结尾)\n";
r = EvaluateExpression();
r = r-48; //字符->数字
printf("结果为:%d\n",r);
return 0;
}