要实现计算任意表达式(如算数表达式和逻辑表达式),首先想到的是输入一个表达式字符串,将其转化为后缀表达式进行计算。因此该问题的第一步是如何将中缀表达式转化为后缀表达式。
利用数据结构中的栈来进行操作,在叙述时,用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