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-----完美结束。