利用后缀表达式实现任意逻辑表达式的运算

要实现计算任意表达式(如算数表达式和逻辑表达式),首先想到的是输入一个表达式字符串,将其转化为后缀表达式进行计算。因此该问题的第一步是如何将中缀表达式转化为后缀表达式。

利用数据结构中的栈来进行操作,在叙述时,用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

 

 

 

  

posted @ 2018-06-12 10:04  "kisetsu  阅读(1893)  评论(0编辑  收藏  举报