数据结构(19)栈典型问题之C++实现表达式求值

来源:互联网 发布:centos7 ssh 端口 编辑:程序博客网 时间:2024/05/17 03:03

  • 导言
  • 表达式求值
    • 算法
    • 算法具体实现

导言

表达式求值是程序设计语言中的一个最基本问题。本次实现采取“算符优先法”。

表达式求值

如何一个表达式都是由操作数、运算符和界限符组成的,我们称为单词。一般地,操作数既可以是常数也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符3类;基本界限符有左右括号和表达式结束符等。

我们把运算符和界限符统称为算符它们构成的集合命名为OP。

我们得到任意的两个相继出现的算符θ1θ2只记得优先级关系至多是下面3种关系之一;
θ1<θ2 : θ1的优先权低于θ2
θ1=θ2 : θ1的优先权等于θ2
θ1>θ2 : θ1的优先权高于θ2

算符优先关系表
这里写图片描述

为实现算法优先算法,可以设置两个工作栈。一个称为OPTR,用以寄存运算符;另一个称为OPND,用以寄存操作数或运算结果。算法基本思路:
1、首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素;
2、依次读入表达式中的每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算比较优先权后做相应的操作,直到表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。

算法

#define OPSETSIZE 7unsigned char Prior[7][7] = {     // 表3.1  算符间的优先关系      '>','>','<','<','<','>','>',      '>','>','<','<','<','>','>',      '>','>','>','>','<','>','>',      '>','>','>','>','<','>','>',        '<','<','<','<','<','=',' ',      '>','>','>','>',' ','>','>',      '<','<','<','<','<',' ','='};      float Operate(float a, unsigned char theta, float b);char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'};Status In(char Test,char* TestOp);char precede(char Aop, char Bop);float EvaluateExpression(char* MyExpression) {  // 算法3.4   // 算术表达式求值的算符优先算法。   // 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。   StackChar  OPTR;    // 运算符栈,字符元素   StackFloat OPND;    // 运算数栈,实数元素   char TempData[20];   float Data,a,b;   char theta,*c,x,Dr[2];   InitStack (OPTR);   Push (OPTR, '#');   InitStack (OPND);   c = MyExpression;   strcpy(TempData,"\0");   while (*c!= '#' || GetTop(OPTR)!= '#') {      if (!In(*c, OPSET)) {         Dr[0]=*c;         Dr[1]='\0';         strcat(TempData,Dr);         c++;         if(In(*c,OPSET)) {            Data=(float)atof(TempData);            Push(OPND, Data);            strcpy(TempData,"\0");         }      } else {   // 不是运算符则进栈         switch (precede(GetTop(OPTR), *c)) {             case '<':   // 栈顶元素优先权低                 Push(OPTR, *c);                   c++;                 break;            case '=':   // 脱括号并接收下一字符                 Pop(OPTR, x);                    c++;                 break;            case '>':   // 退栈并将运算结果入栈                 Pop(OPTR, theta);                 Pop(OPND, b);                   Pop(OPND, a);                                       Push(OPND, Operate(a, theta, b));                  break;         } // switch      }   } // while   return GetTop(OPND);} // EvaluateExpressionfloat Operate(float a,unsigned char theta, float b) {   switch(theta) {      case '+': return a+b;      case '-': return a-b;      case '*': return a*b;      case '/': return a/b;      default : return 0;   } }   Status In(char Test,char* TestOp) {   bool Find=false;   for (int i=0; i< OPSETSIZE; i++) {      if (Test == TestOp[i]) Find= true;   }   return Find;}int ReturnOpOrd(char op,char* TestOp) {   int i;   for(i=0; i< OPSETSIZE; i++) {      if (op == TestOp[i]) return i;   }   return 0;}char precede(char Aop, char Bop) {   return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];}

算法具体实现

参考下面的文档即可
表达式求值实验报告-星空奇人

1 0