栈的应用——表达式求值算法
表达式求值算法
算符优先法:
根据这个运算优先关系的规定来实现对表达式的编译或解释执行的。
算数四则运算规则:
-
先乘除,后加减;,
-
从左算到右;
-
先括号内,后括号外;
任何一个表达式都是由操作数、运算符和界限符组成的,称之为单词。其中运算符和界限符统称为算符
算符间的优先关系
| + | - | * | / | ( | ) | # | |
|---|---|---|---|---|---|---|---|
| + | > | > | < | < | < | > | > |
| - | > | > | < | < | < | > | > |
| * | > | > | > | > | < | > | > |
| / | > | > | > | > | < | > | > |
| ( | < | < | < | < | < | = | |
| ) | > | > | > | > | > | > | |
| # | < | < | < | < | < | = |
为了实现算符优先算法,可以使用两个工作栈。一个称为OPTR,用以寄存运算符;另外一个称做OPND,用以寄存操作数或运算结果;
算法的基本思想如下:
-
首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;
-
依次读入表达式中的每一个字符,若是操作数则进入OPND栈,若是运算符和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕。(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。
求值过程:
1 OperandType EvaluateExpression(){ 2 //算数表达式求值的算符优先算法。 3 //设OPTR和OPND分别为运算符栈和运算数栈。 4 //OP为运算符集合 5 InitStack (OPTR); 6 Push(OPTR,'#'); 7 InitStack(OPND); 8 c=getchar(); 9 while(c!='#' || GetTop(OPTR)!='#'){ 10 if(!In(c,OP)){ 11 Push(OPND,c); 12 c=getchar(); 13 }else{ 14 switch(Precede(GetTop(OPTR),c)){ 15 case '<'://栈顶元素优先权低 16 Push(OPTR,c); 17 c=getchar(); 18 break; 19 case '='://脱括号并接收下一字符 20 Pop(OPTR,x); 21 c=getchar(); 22 break; 23 case '>'://退栈并将运算结果入栈 24 Pop(OPTR,theta); 25 Pop(OPND,b); 26 Pop(OPND,a); 27 Push(OPND,Operate(a,ttheta,b)); 28 break; 29 }//switch 30 } 31 }//while 32 return GetTop(OPND); 33 }//EvaluateExpression
Operate是进行二元运算的函数,如果是编译表达式,则产生这个运算的一组相应指令并返回存放结果的中间变量;如果是解释执行表达式,则直接进行该运算,并返回运算结果。


浙公网安备 33010602011771号