栈的应用:表达式求值(可以算大于等于10的数哦!)

好久不更新,给大家拜个晚年,祝大家2018年每天开开心心,健健康康哈哈哈哈!

/*
表达式求值,改编自严蔚敏版本,可以求解大于等于10的数之间加减乘除的运算,输入一行表达式,以#号结束并回车
编写日期:2018.3.8 15:00-18:23
编译器:Code::Blocks 16.01
使用语言:纯C语言
数据结构类型:栈
*/
#include <stdio.h>
#define MAXSIZE 100
char relation[7][7]={ //全局变量,来自严蔚敏教材53页,这个二维数组表示两个操作符之间的优先级大小关系
                    {'>','>','<','<','<','>','>'},
                    {'>','>','<','<','<','>','>'},
                    {'>','>','>','>','<','>','>'},
                    {'>','>','>','>','<','>','>'},
                    {'<','<','<','<','<','=','/'},
                    {'>','>','>','>','/','>','>'},
                    {'<','<','<','<','<','/','='}
                    };
char op[7]={'+','-','*','/','(',')','#'};//七个操作符,下标从0到6

int find_index(char ch) //在op[]数组中找到和ch一样的操作符并返回其下标,如果找不到则返回-1
{
    for(int i=0;i<7;i++)
        if(op[i]==ch)
            return i;
    return -1;
}

int IsOP(char ch) //判断在OP[]中是否存在和ch一样的操作符,存在返回1否则为0
{
    for(int i=0;i<7;i++)
        if(op[i]==ch)
            return 1;
    return 0;
}

char compare(char a,char b) //a和b都是操作符,该函数输出a和b的优先级次序,如果没有输出结果则返回!
{
    int i,j;
    i=find_index(a);
    j=find_index(b);
    if(i!=-1&&j!=-1&&relation[i][j]!='/')
        return relation[i][j];
    return '!';
}

int compute(int a,int b,char c) //计算a和b在操作符c下的计算结果并返回其值
{
    if(c=='+')
        return a+b;
    if(c=='-')
        return a-b;
    if(c=='*')
        return a*b;
    if(c=='/')
        return a/b;
}

int main()
{
    /*定义char型变量,c是我要输入的一个个字符,OPTR为操作符栈,pri保存两个操作符之间的优先级大小关系,
    theta保存计算前从OPTR栈顶取出的操作符用于后面计算,t用于将c和OPTR栈顶元素进行优先级比较时暂时保存OPTR
    栈顶元素。*/
    char c,OPTR[MAXSIZE],pri,theta,t;
    /*定义int型变量,OPND为操作数栈,top_optr,top_opnd分别为两个栈的指针,sum用于计算大于10的数时采用的中间变量,a和b
    分别表示进行计算时的两个数a和b,res用于保存计算结果,flag用于判断输入是否出错,是一个标志位。*/
    int OPND[MAXSIZE],top_optr,top_opnd,sum,a,b,res,flag;
    top_optr=top_opnd=sum=flag=0;//初始化
    OPTR[++top_optr]='#';//操作符栈先压入#号
    c=getchar();//开始我的输入
    while(c!='#'||OPTR[top_optr]!='#')//只要我输入的不是#,或者操作符栈栈顶不是#,就不停的循环
    {
        if(c>='0'&&c<='9')//如果输入的是数字,要转换为整数型
        {
            sum=sum*10+c-'0';//这是一个技巧哦
            c=getchar();//输入下一个
        }
        else if(IsOP(c))//如果输入的那七个操作符
        {
            if(sum!=0)//先看sum是不是0,如果不是,说明刚才有数字进来了,就把最后一次更新的sum压栈
            {
                OPND[++top_opnd]=sum;
                sum=0;
            }
            t=OPTR[top_optr];//t为目前OPTR栈顶元素
            pri=compare(t,c);//pri为栈顶元素和我输入的操作符的优先级
            if(pri!='!')//不等于!表示我的输入没有出问题
            {
                switch(pri)//进入switch循环
                {
                    case '>':  //如果是大于的话,说明栈顶元素优先级高,就要对OPND弹两次栈,然后OPTR弹一次栈,并对他们进行计算,再将计算后的结果压到OPND中
                        b=OPND[top_opnd--];//OPND第一次弹栈,注意这里是b不是a
                        a=OPND[top_opnd--];//OPND第二次弹栈
                        theta=OPTR[top_optr--];//OPTR弹栈
                        res=compute(a,b,theta);//计算结果
                        OPND[++top_opnd]=res;//结果入OPND栈
                        break;
                    case '<':  //如果小于,直接压栈,然后输入下一个
                        OPTR[++top_optr]=c;
                        c=getchar();
                        break;
                    case '=':  //如果等于,说明此时有一对括号需要脱去(思考一下问什么不可能是两个#相遇),OPTR弹栈一次就好啦,然后输入下一个
                        top_optr--;
                        c=getchar();
                        break;
                }
            }
        }
        else //能执行到这里说明输入的肯定有问题
        {
            printf("error!\n");
            flag=1;
            break;
        }
    }
    if(flag==0) //只要输入没毛病,就输出
        printf("%d\n",OPND[1]);//不要问我为什么答案藏在OPND[1]中,因为OPND[0]不让用。
    return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值