表达式求值(链栈实现)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <conio.h>
  4 
  5 #define _CRT_SECURE_NO_WARNINGS//解决vs下直接用scanf报错
  6 
  7 typedef struct operandstack//操作数栈
  8 {
  9     int Operand;//操作数
 10     struct operandstack* Next;
 11 }OPERAND;
 12 
 13 typedef struct operatorstack//运算符栈
 14 {
 15     char Operator;//运算符
 16     struct operatorstack* Next;
 17 }OPERATOR;
 18 
 19 int Is(char temp);//temp是操作数返回1,否则返回0
 20 void Push_operand(OPERAND* operand_top, int number);//操作数入栈
 21 void Push_operator(OPERATOR* operator_top, char temp);//运算符入栈
 22 int Pop_operand(OPERAND* operand_top);//操作数出栈
 23 char Pop_operator(OPERATOR* operator_top);//运算符出栈
 24 char Precede(char temp1, char temp2);//temp1高优先级就输出‘>',同优先级输出'=', 低优先级输出 '<'
 25 int Operate(int a, char theta, int b);//返回二元运算 a theta b 的结果
 26 
 27 int main(void)
 28 {
 29     char temp = NULL;//输入的字符
 30     int number = 0;//字符转换成操作数
 31     int value = 0;//表达式的值
 32     int a = 0;//a theta b
 33     int b = 0;
 34     char theta = NULL;//二元运算的运算符
 35     OPERAND* operand_top = (OPERAND*)calloc(1, sizeof(OPERAND));//操作数栈顶
 36     OPERATOR* operator_top = (OPERATOR*)calloc(1, sizeof(OPERATOR));//运算符栈顶
 37     OPERAND* operand_s = NULL;//指向操作数栈的指针
 38     OPERATOR* operator_s = NULL;//指向运算符栈的指针
 39     operand_top->Next = NULL;//初始化操作数栈
 40     operator_top->Next = NULL;//初始化运算符栈
 41 
 42     Push_operator(operator_top, '=');//把‘=’压入运算符栈底
 43 
 44     printf("请输入表达式(以=号结尾):");//表达式求值
 45     temp = getchar();//读取首个输入
 46     printf("\n************************************\n");
 47     while (temp != '=' || operator_top->Next->Operator != '=')//输入为‘=’且运算符栈中仅有‘=’时退出循环
 48     {
 49         if (temp == ' ')//忽略空格
 50         {
 51             do
 52             {
 53                 temp = getchar();
 54             } while (temp == ' ');
 55         }
 56         else if (Is(temp) == 1)//temp是操作数返回1,否则返回0
 57         {
 58             printf("\n%c是操作数!", temp);
 59             number = temp - '0';
 60             temp = getchar();//读取下一个输入
 61             while (Is(temp) && temp != ' ')//如果下一个输入还是数字,说明这是同一个操作数
 62             {
 63                 number = 10 * number + (temp - '0');//同一个操作数的不同位
 64                 temp = getchar();
 65             }
 66             Push_operand(operand_top, number);//把操作数压入操作数栈
 67             printf("\n操作数%d进栈了!", number);
 68         }//if是操作数
 69         else//temp是运算符
 70         {
 71             printf("\n%c是运算符!", temp);
 72             printf("\n正在比较输入%c和栈顶运算符%c优先级!", temp, operator_top->Next->Operator);
 73             
 74             switch (Precede(temp, operator_top->Next->Operator))//比较优先级
 75             {
 76             case '>'://temp优先级高
 77                 printf("\n运算符%c进栈了!", temp);
 78                 Push_operator(operator_top, temp);//运算符压入栈
 79                 temp = getchar();
 80                 break;
 81             case '='://两者优先级相同
 82                 Pop_operator(operator_top);
 83                 temp = getchar();
 84                 break;
 85             case '<'://temp优先级低
 86                 //将出栈的两个操作数及运算符进行二元运算,运算结果压入操作数栈
 87                 value = Operate(Pop_operand(operand_top) , Pop_operator(operator_top), Pop_operand(operand_top));
 88                 printf("\n二元运算的值为:%d", value);
 89                 printf("\n操作数%d进栈了!", value);
 90                 Push_operand(operand_top, value);//运算结果压入栈
 91                 break;
 92             default:
 93                 printf("\n优先级错误!");
 94                 exit(-1);
 95             }//switch
 96         }//else
 97     }//while
 98 
 99     if (operand_top->Next == NULL)//操作数栈中没有操作数报错
100     {
101         printf("\n表达式求值错误!");
102         exit(-1);
103     }
104     printf("\n\n************************************\n");
105     printf("\n表达式的值为%d\n", operand_top->Next->Operand);
106     printf("\n************************************\n");
107     system("pause");
108     return 0;
109 }
110 
111 int Is(char temp)//temp是操作数返回1,是运算符返回0
112 {
113     char a[7] = { '+', '-', '*', '/', '(', ')', '=' };//运算符
114     int i;
115     if (temp >= '0' && temp <= '9')
116     {
117         return 1;
118     }
119     for (i = 0; a[i] != '\0'; i++)
120     {
121         if (a[i] == temp)
122         {
123             return 0;
124         }
125     }
126     printf("\n输入的既不是操作数也不是操作符!");
127     exit(-1);
128 }
129 
130 void Push_operand(OPERAND* operand_top, int number)//把操作数压入操作数栈
131 {
132     OPERAND* operand_s;
133     if ((operand_s = (OPERAND*)calloc(1, sizeof(OPERAND))) == NULL)
134     {
135         printf("\nclear allocation fail !");
136         exit(-1);
137     }
138     operand_s->Operand = number;
139     operand_s->Next = operand_top->Next;
140     operand_top->Next = operand_s;
141 }
142 
143 void Push_operator(OPERATOR* operator_top, char temp)//把运算符压入运算符栈
144 {
145     OPERATOR* operator_s;
146     if ((operator_s = (OPERATOR*)calloc(1, sizeof(OPERATOR))) == NULL)//把‘=’压入栈底
147     {
148         printf("\nclear allocation fail !");
149         exit(-1);
150     }
151     operator_s->Operator = temp;
152     operator_s->Next = operator_top->Next;
153     operator_top->Next = operator_s; 
154 }
155 
156 int Pop_operand(OPERAND* operand_top)//操作数出栈
157 {
158     int temp;
159     OPERAND* p;
160     p = operand_top->Next;
161     temp = p->Operand;
162     operand_top->Next = p->Next;
163     free(p);
164     //printf("\n返回%d", temp);
165     return temp;
166 }
167 
168 char Pop_operator(OPERATOR* operator_top)//操作符出栈
169 {
170     char temp;
171     OPERATOR* p;
172     if (operator_top->Next == NULL)
173     {
174         printf("\n空栈!");
175         exit(-1);
176     }
177     p = operator_top->Next;
178     temp = p->Operator;
179     operator_top->Next = p->Next;
180     free(p);
181     return temp;
182 }
183 
184 char Precede(char temp1, char temp2)//比较优先级,temp1高优先级就输出‘>',同优先级输出'=',temp1低优先级输出 '<'
185 {
186     switch (temp1)
187     {
188     case '+':
189     case '-':
190         switch (temp2)
191         {
192         case '(':
193         case '=':
194             return '>';
195             break;
196         case '+':
197         case '-':
198         case '*':
199         case '/':
200         case ')':
201             return '<';
202             break;
203         default:
204             printf("\n优先级比较错误!");
205             exit(-1);
206         }
207     case '*':
208     case '/':
209         switch (temp2)
210         {
211         case '+':
212         case '-':
213         case '=':
214         case '(':
215             return '>';
216             break;
217         case '*':
218         case '/':
219         case ')':
220             return '<';
221             break;
222         default:
223             printf("\n优先级比较错误!");
224             exit(-1);
225         }
226     case '(':
227         switch (temp2)
228         {
229         case '+':
230         case '-':
231         case '*':
232         case '/':
233         case '(':
234             return '>';
235             break;
236         default:
237             printf("\n优先级比较错误!");
238             exit(-1);
239         }
240     case ')':
241         switch (temp2)
242         {
243         case '+':
244         case '-':
245         case '*':
246         case '/':
247             return '<';
248             break;
249         case '(':
250             return '=';
251             break;
252         default:
253             printf("\n优先级比较错误!");
254             exit(-1);
255         }
256     case '=':
257         switch (temp2)
258         {
259         case '+':
260         case '-':
261         case '*':
262         case '/':
263         case '(':
264             return '<';
265             break;
266         case '=':
267             return '=';
268             break;
269         default:
270             printf("\n优先级比较错误!");
271             exit(-1);
272         }
273     default:
274         printf("\n优先级比较错误!");
275         exit(-1);
276     }
277 }
278 
279 int Operate(int a, char theta, int b)//返回二元运算 a theta b 的结果
280 {
281     switch (theta)
282     {
283     case '+':
284         return a + b;
285         break;
286     case '-':
287         return a - b;
288         break;
289     case '*':
290         return a * b;
291         break;
292     case '/':
293         if (b == 0)
294         {
295             printf("\n分母不能为0!");
296             exit(-1);
297         }
298         return a / b;
299         break;
300     default:
301         printf("\n二元运算错误!");
302         exit(-1);
303     }
304 }

 

posted @ 2021-12-12 22:36  吕辉  阅读(185)  评论(0)    收藏  举报