導言 運算式求值 演算法 演算法具體實現
導言
運算式求值是程式設計語言中的一個最基本問題。本次實現採取“算符優先法”。 運算式求值
如何一個運算式都是由運算元、運算子和界限符組成的,我們稱為單詞。一般地,運算元既可以是常數也可以是被說明為變數或常量的標識符;運算子可以分為算術運算子、關係運算子和邏輯運算子3類;基本界限符有左右括弧和運算式結束符等。
我們把運算子和界限符統稱為算符它們構成的集合命名為OP。
我們得到任意的兩個相繼出現的算符 θ1 \theta_1 和 θ2 \theta_2隻記得優先順序關係至多是下面3種關係之一;
θ1<θ2 \theta_1 : θ1 \theta_1 的優先權低於 θ2 \theta_2
θ1=θ2 \theta_1 = \theta_2 : θ1 \theta_1 的優先權等於 θ2 \theta_2
θ1>θ2 \theta_1 > \theta_2 : θ1 \theta_1 的優先權高於 θ2 \theta_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)];}
演算法具體實現
參考下面的文檔即可
運算式求值實驗報告-星空奇人