要實現計算任意表達式(如算數表達式和邏輯表達式),首先想到的是輸入一個表達式字符串,將其轉化為后綴表達式進行計算。因此該問題的第一步是如何將中綴表達式轉化為后綴表達式。
利用數據結構中的棧來進行操作,在敘述時,用S="..."來代表棧及其元素,如S="A1B2C3"表示A為棧底元素,3為棧頂元素;O表示輸出結果
以1+2×(3-4)-4/2為例,具體方法如下:
1)若表達式沒有被讀取完,讀取表達式的下一個字符,否則彈出棧內所有元素
2)如果是數字,直接輸出,轉到第1步,否則轉到第3步
3)表達式為括號或運算符,有以下幾種情況:
a.是左括號——入棧;
b.是右括號——將棧內左括號之后的符號依次彈出;
c.是運算符,棧為空或優先級大於當前棧頂元素(包括左括號)——入棧;
d.是運算符且優先級小於等於當前棧頂元素——將棧內優先級大於或等於該運算符的元素依次彈出,之后該符號入棧;
轉第1步
根據以上原則,在對例子進行轉換時的步驟為:
1)根據2,"1"輸出,S="",O="1";
2)根據3.c,"+"入棧,S="+",O="1";
3)根據2,"2"輸出,,S="+",O="12";
4)根據3.c,"×"入棧,S="+×",O="12";
5)根據3.a,"("入棧,S="+×(",O="12";
6)根據2,"3"輸出,S="+×(",O="123"
6)根據3.c,"-"入棧,S="+×(-",O="123";
6)根據2,"4"輸出,S="+×(-",O="1234"
4)根據3.b,"-"出棧,S="+×",O="1234-";
4)根據3.d,"×"、"+"依次出棧,之后"-"入棧,S="-",O="1234-×+";
4)根據2,"4"輸出,S="-",O="1234-×+4";
4)根據3.c,"/"入棧,S="-/",O="1234-×+4";
4)根據2,"2"輸出,,S="-/",O="1234-×+42";
4)表達式讀取完,"/"、"-"依次輸出,S="",O="1234-×+42/-";
邏輯表達式的轉換方法類似,只需重新考慮邏輯運算符的優先級
下面以一個邏輯表達式為例,給出實現代碼
1 #include <iostream> 2 #include <string> 3 #include <cstdlib> 4 #include <cmath> 5 using namespace std; 6 7 bool calculate(string expression){ 8 //存符號的棧 9 char *stack=(char*)malloc(sizeof(char)*20); 10 //輸出后綴表達式的棧 11 char *output=(char*)malloc(sizeof(char)*20); 12 //符號棧頂 13 int stackTop=0; 14 //輸出表達式的棧頂 15 int outputTop=0; 16 for(int i=0;i<expression.length();i++){ 17 char ch=expression[i]; 18 if(ch>='A'&&ch<='Z'){ 19 output[outputTop]=ch; 20 outputTop++; 21 }else{ 22 switch(ch){ 23 case '~': 24 stack[stackTop]=ch; 25 stackTop++; 26 break; 27 case '(': 28 stack[stackTop]=ch; 29 stackTop++; 30 break; 31 case ')': 32 while(stack[stackTop-1]!='('){ 33 output[outputTop]=stack[stackTop-1]; 34 outputTop++; 35 stackTop--; 36 } 37 stackTop--; 38 break; 39 case '&': 40 while(stack[stackTop-1]=='~'){ 41 output[outputTop]=stack[stackTop-1]; 42 outputTop++; 43 stackTop--; 44 } 45 stack[stackTop]=ch; 46 stackTop++; 47 break; 48 case '|': 49 while(stack[stackTop-1]=='~'||stack[stackTop-1]=='&'){ 50 output[outputTop]=stack[stackTop-1]; 51 outputTop++; 52 stackTop--; 53 } 54 stack[stackTop]=ch; 55 stackTop++; 56 break; 57 case '>': 58 while(stack[stackTop-1]=='~'||stack[stackTop-1]=='&'||stack[stackTop-1]=='|'){ 59 output[outputTop]=stack[stackTop-1]; 60 outputTop++; 61 stackTop--; 62 } 63 stack[stackTop]=ch; 64 stackTop++; 65 break; 66 } 67 } 68 } 69 70 71 while(stackTop>0){ 72 output[outputTop]=stack[stackTop-1]; 73 outputTop++; 74 stackTop--; 75 } 76 output[outputTop]='\0'; 77 for(int i=0;i<20;i++){ 78 stack[i]='\0'; 79 } 80 cout<<output<<endl; 81 //計算表達式里有幾個變量 82 bool *vals=(bool*)malloc(sizeof(bool)*10); 83 bool *valStack=(bool*)malloc(sizeof(bool)*10); 84 int valStackTop=0; 85 int numOfVars=0; 86 87 for(int i=0;output[i]!='\0';i++) { 88 char ch = output[i]; 89 if (ch >= 'A' && ch <= 'Z') { 90 for (int j = 0; j <= stackTop; j++) { 91 if (stack[j] == ch) { 92 break; 93 } 94 if (j == stackTop) { 95 numOfVars++; 96 stack[stackTop]=ch; 97 stackTop++; 98 break; 99 } 100 } 101 } 102 } 103 104 bool valTable[3]={1,0,1}; 105 106 for(int i=0;output[i]!='\0';i++){ 107 char ch=output[i]; 108 if(ch>='A'&&ch<='Z'){ 109 for(int j=0;j<3;j++){ 110 if(ch==stack[j]){ 111 valStack[valStackTop]=valTable[j]; 112 valStackTop++; 113 break; 114 } 115 } 116 }else{ 117 switch(ch){ 118 case '~': 119 valStack[valStackTop-1]=!valStack[valStackTop-1]; 120 break; 121 case '&': 122 valStack[valStackTop-2]=valStack[valStackTop-1]&&valStack[valStackTop-2]; 123 valStackTop--; 124 break; 125 case '|': 126 valStack[valStackTop-2]=valStack[valStackTop-1]||valStack[valStackTop-2]; 127 valStackTop--; 128 break; 129 case '>': 130 valStack[valStackTop-2]=!valStack[valStackTop-2]||valStack[valStackTop-1]; 131 valStackTop--; 132 break; 133 } 134 } 135 for(int j=0;j<valStackTop;j++){ 136 cout<<valStack[j]; 137 } 138 cout<<endl; 139 } 140 return valStack[0]; 141 } 142 int main() { 143 cout << "Hello, World!" << std::endl; 144 string expr="A&(B|A)|((A>C)&~B)"; 145 cout<<"表達式結果為"<<calculate(expr)<<endl; 146 return 0; 147 }
運行結果:
ABA|&AC>B~&| 1 10 101 11 1 11 111 11 110 111 11 1 表達式結果為1