表达式求值

来源:互联网 发布:k歌软件电视 编辑:程序博客网 时间:2024/04/30 19:46

                    

    题目:一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正整数,运算符只含加减乘除等四种运算符,编程利用“算符优先法”求算术表达式的值。

[要求]从键盘读入一个合法的算术表达式,输出正确的结果。


分割线里面内容摘自:blog.csdn.net/arduousbonze/article/details/3128084

-------------------------------------------------------------------------------------------------------------

中缀表达式到后缀表达式的转换
     要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式,必须了解操作符的优先级和结合性。优先级或者说操作符的强度决定求值顺序;优先级高的操作符比优先级低的操作符先求值。如果所有操作符优先级一样,那么求值顺序就取决于它们的结合性。操作符的结合性定义了相同优先级操作符组合的顺序(从右至左或从左至右)。
转换过程包括用下面的算法读入中缀表达式的操作数、操作符和括号:
          1. 初始化一个空堆栈,将结果字符串变量置空。
          2. 从左到右读入中缀表达式,每次一个字符。
          3. 如果字符是操作数,将它添加到结果字符串。
          4. 如果字符是个操作符,弹出(pop)操作符,直至遇见开括号(opening parenthesis)、优先级较低的操作符或者同一优先    级的右结合符号。把这个操作符压入(push)堆栈。
         5. 如果字符是个开括号,把它压入堆栈。
         6. 如果字符是个闭括号(closing parenthesis),在遇见开括号前,弹出所有操作符,然后把它们添加到结果字符串。
         7. 如果到达输入字符串的末尾,弹出所有操作符并添加到结果字符串。


     后缀表达式求值(关于后缀表达式的实现可以看看这简单逆波兰计算器
  对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。您可以用如下算法对后缀表达式求值:
      1. 初始化一个空堆栈
      2. 从左到右读入后缀表达式
     3. 如果字符是一个操作数,把它压入堆栈。

     4. 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
     5. 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。
         

-------------------- ________________________________ ---------------------------------- --------------------------------- -------------------------- -----------------------------------------


看了这么多理论,还是看代码吧:

** @description:表达式求值1.使用两个工作栈,一个放运算符,另一个方操作数和结果2.当"(" = ")" 时表示左右括号相遇,括号内运算完成,#与#相遇表示表达式运算完成(在左边预设一个#)3.初始化两栈,#入运算符栈4.读入字符,判断是否为操作符,否则入操作数栈,为操作符则根据优先级进行操作* @return ElemType elem*/SElemType EvaluateExpression() {LinkStack OPTR; //操作符栈SqStack OPND; //操作数栈char c,elem,tmp,operator;int a,b,d;InitStack(&OPTR);Push(&OPTR,'#');InitStack1(&OPND);c = getchar();GetTop(OPTR,&elem);while(c != '#' || elem != '#' ) {//不是操作符则进OPND栈if(isdigit(c)) {c = c - '0';Push1(&OPND,c);c = getchar();}else {switch(compare(c,elem)) {case '<':Push(&OPTR,c);c = getchar();break;case '=':Pop(&OPTR,&tmp);c = getchar();break;case '>':Pop(&OPTR,&operator);Pop1(&OPND,&a);Pop1(&OPND,&b);Push1(&OPND,Operate(a,operator,b));break;default:exit(OVERFLOW);break;}}GetTop(OPTR,&elem);}GetTop1(OPND,&d);return d; }//求值int Operate(int a,char c,int b) {int result;result = 0;switch(c) {case '+':result = a + b;break;case '-':result = b - a;break;case '*':result = a * b;break;case '/':if(a != 0)result = b / a;elseexit(OVERFLOW);break;default:exit(OVERFLOW);break;}return result;}//获取操作符的位置,返回它的位置,如果不是其中的操作符则返回-1int IsOperator(char c) {int i;char op[7] = {'+','-','*','/','(',')','#'};for(i = 0; i < 7; i++ ) {if(op[i] == c)return i;}return -1;}//比较返回两个操作符的优先等级,=  > < 等char compare(char c,char elem) {char str[7][7] = {       //+   -   *   /   (   )   # '>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>','<','<','<','<','<','=',' ','>','>','>','>',' ','>','>','<','<','<','<','<',' ','='};int i,j;i = IsOperator(c);j = IsOperator(elem);if(i >= 7 || j >= 7)return ERROR;return str[j][i];}


完整的代码看:GitHub


0 0
原创粉丝点击