Data Structure——四则运算(栈的运用)

#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;    

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值