运算时求值核心思想:将运算式逐字符读取,若是运算数就进运算数栈,若是运算符就与运算符栈顶比较运算符的优先级来做相应的操作。直到遇到运算式的结束符且运算符栈里没有运算符为止。
因为用到了两个栈(运算符栈和运算数栈)且这两个栈的基本存储类型还不一样,一个为char类型存储运算符,而另一个为float类型存储数值的。所以就调用了两个栈的头文件Stack_Float.h和Stack_Char.h。两个头文件实现的基本操作是一样的,只是里面的结构体类型进行了改动。如下:
1 /*Stack_Char.h*/ 2 typedef char CElemType; 3 typedef struct 4 { 5 CElemType data[MAXSIZE]; 6 int top; 7 }StackChar;
1 /*Stack_Float.h*/ 2 typedef float FElemType; 3 typedef struct 4 { 5 FElemType data[MAXSIZE]; 6 int top; 7 }StackFloat;
还有栈的基本操作函数GetTop函数进行了改动。为了方便之后函数功能的实现,将数值参数去掉了,为了省事也去掉了对栈是否为空的判断,不管栈如何直接返回栈顶元素,容易出错。其他的基本函数与之前写的栈的顺序实现一样,记得将所有宏类型名称替换。GetTop函数如下以char类型为例:
1 CElemType GetTop(StackChar S) 2 { 3 return S.data[S.top]; 4 }
核心代码实现如下:
1 #include "Stack_Float.h" 2 #include "Stack_Char.h" 3 #include "string.h" 4 5 unsigned char Prior[7][7] = { 6 '>','>','<','<','<','>','>', 7 '>','>','<','<','<','>','>', 8 '>','>','>','>','<','>','>', 9 '>','>','>','>','<','>','>', 10 '<','<','<','<','<','=',' ', 11 '>','>','>','>',' ','>','>', 12 '<','<','<','<','<',' ','=' 13 }; //算符间的优先关系,对应的实现关系在代码下面抛出 14 15 #define OPSETSIZE 7 16 char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; //运算符集;运算符先支持+-*/,#为结束符 17 18 //返回a与b的运算结果 19 float Operate(float a, unsigned char theta, float b) 20 { 21 switch(theta) 22 { 23 case '+': 24 return a+b; 25 case '-': 26 return a-b; 27 case '*': 28 return a*b; 29 case '/': 30 return a/b; 31 default : 32 return 0; 33 } 34 } 35 36 //判断Test字符是否在运算符集里 37 Status In(char Test, char* TestOp) 38 { 39 bool Find = false; 40 for (int i = 0; i< OPSETSIZE; i++) 41 { 42 if (Test == TestOp[i]) Find = true; 43 } 44 return Find; 45 } 46 47 //返回运算符在运算符集里的位置 48 int ReturnOpOrd(char op,char* TestOp) 49 { 50 int i; 51 for(i = 0; i < OPSETSIZE; i++) 52 { 53 if (op == TestOp[i]) return i; 54 } 55 return 0; 56 } 57 58 //返回两个运算符的优先级 59 char precede(char Aop, char Bop) 60 { 61 return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)]; 62 } 63 64 //求解运算式 65 float EvaluateExpression(char* MyExpression) 66 { 67 StackChar OPTR; // 运算符栈,字符元素 68 StackFloat OPND; // 运算数栈,实数元素 69 char TempData[20]; 70 float Data,a,b; 71 char theta,*c,x,Dr[2]; 72 /*初始化栈 73 /*运算符栈先进栈一个#结束符做开始*/ 74 InitStack (OPTR); 75 Push (OPTR, '#'); 76 InitStack (OPND); 77 c = MyExpression; //c指向求解的运算式 78 strcpy_s(TempData,"