数据结构(C语言版)严蔚敏:第三章:栈与队列---栈的应用---p52表达式求值的算法详细分析
admin
2023-07-27 07:40:09
0次

P53 页   表达式求值----请先查看相应书籍,至少先了解下p53页的算符间优先关系表。

       算法3.4 : 描述“算符优先算法”的求值过程

表达式原文

OperandType EvaluateExpression(){

       //算术表达式求值的算符优先算法。设OPTN和OPND分别为运算符栈和运算数栈

       //OP为运算符集合

       InitStack(OPTR); Push(OPTR,’#’);

       initStack(OPND); c = getchar();

       while (c != ‘#’ || GetTop(OPTR) != ‘#’){

              if(! In(c,OP)){Push(OPND,c); c = getchar();}

              else

                     switch (Precede(GetTop(OPTR),c)){

       case ‘<’ :    //栈顶元素优先权低

              Push(OPTR,c); c = getchar();

              break;

       case ‘=’ :             //脱括号并接收下一字符

              Pop(OPTR,x); c = getchar();

              Break;

       Case ‘>’ :    //退栈并将运算结果入栈

              Pop(OPTR,theta);

              Pop(OPND,b);

              Pop(OPND,a);

              Push(OPND,Operate(a,theta,b);

              Break;

}//switch

}//while

Return Gettop(OPND);

}//EvaluateExpression

语句分析

OperandType EvaluateExpression(){

       //算术表达式求值的算符优先算法。设OPTN和OPND分别为运算符栈和运算数栈

       //OP为运算符集合

       InitStack(OPTR);              //初始化OPTR栈

Push(OPTR,’#’);               //将“#”放入到OPTR栈的栈底

 

       initStack(OPND);             //初始化OPND栈

c = getchar();                   //获取一个从键盘输入的字符

       //接下来的代码将处理这个字符

       while (c != ‘#’ || GetTop(OPTR) != ‘#’){

              //只要c(从键盘获取的字符)不等于“#“ 或者从OPTR获取的栈顶元素不是”#“时,就一直循环。|| 逻辑运算符,只要有一个为真就为真,所以只要有一个遇到了#就会退出循环。

              if(! In(c,OP)){Push(OPND,c);

                     //如果 c这个字符在OP这个集合中不存在。就是判断c是不是输入的运算符。如果不是去处符,则将c的字符入栈到OPND栈中去。

c = getchar();}

//然后再提示用户输入下一个字符

              else

//否则的话,c就是OP集合中,说明c是个运算符

                     switch (Precede(GetTop(OPTR),c)){

                                   //precede 应该是一个优先级比较的函数,将GetTop(OPTR)从OPTR的栈顶元素获取到的去处符与c进行比较优先级。

       case ‘<’ :    //栈顶元素优先权低

              Push(OPTR,c);

c = getchar();

              break;

              //如果是栈顶元素的优先级低,则将输入的c入栈到OPTR栈,并再接收下一个字符

       case ‘=’ :             //脱括号并接收下一字符

              Pop(OPTR,x);

c = getchar();

              Break;

              //如果两个运算符优先级相等的时候,也就是要么是左右括号匹配了,要么是#匹配了,但是这里不可能是#号,因为不是#是进入这个循环的条件。

       Case ‘>’ :    //退栈并将运算结果入栈

              Pop(OPTR,theta);

              Pop(OPND,b);

              Pop(OPND,a);

              Push(OPND,Operate(a,theta,b);

              Break;

              //如果是栈内的优先级大于获取的运算符,则先处理栈内的运算符。也就是先将栈顶的元素出栈后先进行运算,然后将结果入到栈内去。

}//switch

}//while

Return Gettop(OPND);

}//EvaluateExpression


 

分步骤分析:

4+2*3-10/5

 

第一步:判断4是否是运算符,不是运算符,则4入OPND栈,并获取下一个字符

第二步:+号与OPTR栈内的top元素比较优先级,top元素是一个#号,+号的优先级大于#号(任何运算符的运算优先级都大于#号,只有#自己与自己相等),+号入OPTR栈,并获取下一个字符

第三步:判断2是否是运算符,不是运算符,2入OPND栈,并获取下一个字符,

第四步::获取到的一个字符为“*“乘号。与OPTR栈顶的元素+号进行比较优先级,乘号优先,所以乘号直接入OPTR栈,然后获取下一个元素。

第五步:获取到的下一个元素是3,是一个操作数,不是运算符,所以直接入栈。再获取下一个元素。

第六步:获取到的元素为-号,-号与OPTR栈顶元素进行比较,是个乘号,所以乘号优先。

                     从OPTR栈中,乘号出栈

                     从OPND中,出栈两个OPND的数,一个是栈顶元素3,另外一个是次栈顶元素2.

                     先进行计算,3*2=6

                     将6入到OPND栈

                     获取下一个元素

第七步:获取到的下一个元素为-号,-号与栈顶元素进行比较,是个+号,栈里的元素是1,输出的符号为2,+与-号,谁在栈内谁优先。所以得先把栈内的算完,明细如下:

                     从OPTR中出栈+号

                     从OPND中出栈两个数,1个为上一步算出来的6,另外一个为4

                     进行计算,6+4=10

                     将10这个元素入栈到OPND栈中去

                     获取下一个元素

第八步:获取的元素为10,是一个操作数,数直接入栈到OPND栈中去,获取下一个元素

第九步:获取到的下一个元素为为/,与OPTR栈顶元素进行对比。/号优先,所以直接入栈到OPTR栈中去。获取下一个元素。

第十步:下一个元素为5,5是一个操作数,直接入栈到OPND栈中去,获取下一个元素。

第十一步:此时表示式已经完了,所以下一个输入的字符为“#“号。而#号遇到任何其它运算符都是低优先级的,所以此时的OPTR的栈顶元素为/,/的优先级大于#号的优先级,所以操作步骤如下:

                     从OPTR中出栈一个运算符/

                     从OPND中出栈两个数,一个是10,一个为5

                     10/5=2

                     将运算的结果2入栈到OPND中去。

                     获取下一个字符

第十二步:又是#号,再操作一遍

                     10-2=8

                     8入栈

第十三步:又是#号,再拉取栈顶元素,而此是的栈顶元素已经是#号了,所以此是循环结束

第十四步:return OPND的栈顶元素为8-----完美结束。


相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...