求表达式的值--栈和队列的应用

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3
  4 #define OK 1
  5 #define ERROR 0
  6 #define STACK_SIZE 20
  7 #define STACK_INCREMENT 10
  8 #define QUEUE_SIZE 20
  9
 10 typedef int Status;
 11
 12 typedef char StackElemtype;
 13 typedef struct Stack{
 14     StackElemtype* base;
 15     StackElemtype* top;
 16     int stackSize;
 17 }Stack;
 18 Status StackInit(Stack* s){
 19     s->base = (StackElemtype*)malloc(sizeof(StackElemtype) * STACK_SIZE);
 20     if( !s->base )
 21         return ERROR;
 22     s->top = s->base;
 23     s->stackSize = STACK_SIZE;
 24     return OK;
 25 }
 26 Status Pop(Stack* s,StackElemtype* value){
 27     if( s->base == s->top ){
 28         printf("\nstack empty\n");
 29         return ERROR;
 30     }
 31     *value = *(--(s->top));
 32     return OK;
 33 }
 34 Status Push(Stack* s,StackElemtype value){
 35     if( s->top - s->base == s->stackSize){
 36
 37         s->base = (StackElemtype*)realloc(s->base,sizeof(StackElemtype) * (STACK_INCREMENT + STACK_SIZE));
 38         if( !s->base )
 39             return ERROR;
 40         s->top = s->base + STACK_SIZE;
 41         s->stackSize = STACK_SIZE + STACK_INCREMENT;
 42     }
 43     *(s->top) = value;
 44     s->top++;
 45     return OK;
 46 }
 47 int StackLength(Stack s){
 48     return s.top - s.base;
 49 }
 50
 51 typedef double StackElemtype_ForValueExperssion;
 52 typedef struct Stack_2{
 53     StackElemtype_ForValueExperssion* base;
 54     StackElemtype_ForValueExperssion* top;
 55     int stackSize;
 56 }Stack_2;
 57 Status StackInit_2(Stack_2* s){
 58     s->base = (StackElemtype_ForValueExperssion*)malloc(sizeof(StackElemtype_ForValueExperssion) * STACK_SIZE);
 59     if( !s->base )
 60         return ERROR;
 61     s->top = s->base;
 62     s->stackSize = STACK_SIZE;
 63     return OK;
 64 }
 65 Status Pop_2(Stack_2* s,StackElemtype_ForValueExperssion* value){
 66     if( s->base == s->top ){
 67         printf("\nstack empty\n");
 68         return ERROR;
 69     }
 70     *value = *(--(s->top));
 71     return OK;
 72 }
 73 Status Push_2(Stack_2* s,StackElemtype_ForValueExperssion value){
 74     if( s->top - s->base == s->stackSize){
 75         s->base = (StackElemtype_ForValueExperssion*)realloc(s->base,sizeof(StackElemtype_ForValueExperssion) * (STACK_INCREMENT + STACK_SIZE));
 76         if( !s->base )
 77             return ERROR;
 78         s->top = s->base + STACK_SIZE;
 79         s->stackSize = STACK_SIZE + STACK_INCREMENT;
 80     }
 81     *(s->top) = value;
 82     s->top++;
 83     return OK;
 84 }
 85
 86 typedef double QueueElemtype;
 87 typedef char   QueueOperatorValue;
 88 typedef struct QueueNode{
 89     QueueElemtype data;
 90     QueueOperatorValue operator;
 91     struct QueueNode* next;
 92     int flag;
 93 }QueueNode,*QueueNodePtr;
 94 typedef struct Queue{
 95     QueueNodePtr front;
 96     QueueNodePtr rear;
 97 }Queue;
 98
 99 Status QueueInit(Queue* q){
100     q->front = (QueueNodePtr)malloc(sizeof(QueueNode));
101     if( !q->front )
102         return ERROR;
103     q->rear = q->front;
104     q->rear->next = NULL;
105     return OK;
106 }
107 Status QueueInsert(Queue* q,QueueElemtype value){
108     QueueNodePtr new;
109     new = (QueueNodePtr)malloc(sizeof(QueueNode));
110     if( !new )
111         return ERROR;
112     new->data = value;
113     new->flag = 1;
114     new->next = NULL;
115     q->rear->next = new;
116     q->rear = new;
117     return OK;
118 }
119 Status QueueInsert_operatorValue(Queue* q,QueueOperatorValue value){
120     QueueNodePtr new;
121     new = (QueueNodePtr)malloc(sizeof(QueueNode));
122     if( !new )
123         return ERROR;
124     new->operator = value;
125     new->flag = 0;
126     new->next = NULL;
127     q->rear->next = new;
128     q->rear = new;
129     return OK;
130 }
131 Status QueueDelete(Queue* q,QueueElemtype* value,QueueOperatorValue *operator,int* symbol){
132     QueueNodePtr first;
133     if( q->front == q->rear )
134         return ERROR;
135     first = q->front->next;
136     if( first->flag == 1 ){
137         *value = first->data;
138         *symbol = 1;
139     }
140     else{
141         *operator = first->operator;
142         *symbol = 0;
143     }
144     q->front->next = first->next;
145     if( first == q->rear ){
146         q->rear = q->front;
147     }
148     return OK;
149 }
150
151 /* 利用栈将中缀表达式转化为后缀表达式:
152  * ——————————————————————————————————————————————————————————————
153  * |  用户的输入    |            进行的处理                        |
154  * |    0~9:      | 直接输出到控制台                              |
155  * |    /,*,(    | 直接Push                                     |
156  * |    +,-       | 将栈中的元素Pop直到1.栈空或者是2.遇到(          |
157  * |    )          | 在遇到(之前将栈中的元素全部Pop                 |
158  * ——————————————————————————————————————————————————————————————
159  * */
160
161 Status Infix2Postfix(Queue* q){
162     //Queue q;
163     //QueueInit(&q);
164     Stack s;
165     StackInit(&s);
166     char c,e;
167     char bufferDigit[10];
168     int i = 0;
169     double longDigit;
170     printf("       Please Enter Infix Expression\n");
171     printf("------------NOTE: end of ‘#‘--------------\n");
172     scanf("%c", &c);
173     while( ‘#‘ != c){
174         while( c <= ‘9‘ && c >= ‘0‘ || ‘.‘ == c ){
175             bufferDigit[i++] = c;
176             bufferDigit[i] = ‘\0‘;
177             scanf("%c", &c);
178             if(!((c <= ‘9‘ && c >= ‘0‘ ) || ‘.‘ == c )){
179                 longDigit = atof(bufferDigit);
180                 QueueInsert(q,longDigit);
181                 i = 0;
182             }
183         }
184         if( ‘(‘ == c || ‘*‘ == c || ‘/‘ == c ){
185             Push(&s, c);
186         }
187         else if( ‘+‘ == c || ‘-‘ == c ){
188             if( !StackLength(s) )
189                 Push(&s, c);
190             else{
191                 Pop(&s, &e);
192                 while( ‘(‘ != e ){
193                     QueueInsert_operatorValue(q, e);
194                     if( StackLength(s) == 0 ){
195                         break;
196                     }else
197                         Pop(&s, &e);
198                 }
199                 if( ‘(‘ == e )
200                     Push(&s, e);
201                 Push(&s, c);
202             }
203         }else if( ‘)‘ == c ){
204             Pop(&s, &e);
205             while( ‘(‘ != e ){
206                 QueueInsert_operatorValue(q, e);
207                 Pop(&s, &e);
208             }
209         }else if( ‘#‘ == c){
210             break;
211         }else{
212             printf("input ERROR!\n");
213             return ERROR;
214         }
215         scanf("%c", &c);
216     }
217     while(StackLength(s)){
218         Pop(&s, &e);
219         QueueInsert_operatorValue(q, e);
220     }
221     QueueInsert_operatorValue(q,‘#‘);
222     return OK;
223 }
224 Status ShowQueue(Queue q){
225     printf("The Reverse Polish Notation is:");
226     if(q.front == q.rear){
227         printf("Queue Empty");
228         return ERROR;
229     }
230     QueueNodePtr p = q.front->next;
231     while(p != q.rear){
232         if(p->flag)
233             printf("%g  ", p->data);
234         else
235             printf("%c  ", p->operator);
236         p = p->next;
237     }
238     printf("\n");
239     return OK;
240 }
241
242 /* 利用栈求解后缀表达式(逆波兰表达式)的值。
243  *  ——————————————————————————————————————————————————————————————————————
244  * |   +,-,*,/,     |     将栈顶的两个元素弹出进行计算,将结果压入栈顶      |
245  * |  数字             |     将其压入栈顶                                  |
246  *  ———————————————————————————————————————————————————————————————————————
247  * */
248 Status ValueExpression(Queue q){
249     Stack_2 s;
250     StackInit_2(&s);
251     double o1;
252     double o2;
253     QueueElemtype number;
254     QueueOperatorValue operator;
255     int symbol;
256     QueueDelete(&q,&number,&operator,&symbol);
257     while( symbol == 1 || ( symbol == 0 && ‘#‘ != operator)){
258         if(symbol == 1){
259             Push_2(&s, number);
260         }
261         else if(symbol == 0){
262             switch(operator){
263                 case ‘+‘:
264                     Pop_2(&s,&o1);
265                     Pop_2(&s,&o2);
266                     Push_2(&s,o2 + o1);
267                     break;
268                 case ‘-‘:
269                     Pop_2(&s,&o1);
270                     Pop_2(&s,&o2);
271                     Push_2(&s,o2 - o1);
272                     break;
273                 case ‘*‘:
274                     Pop_2(&s,&o1);
275                     Pop_2(&s,&o2);
276                     Push_2(&s,o2 * o1);
277                     break;
278                 case ‘/‘:
279                     Pop_2(&s,&o1);
280                     Pop_2(&s,&o2);
281                     Push_2(&s,o2 / o1);
282                     break;
283             }
284         }
285         QueueDelete(&q,&number,&operator,&symbol);
286     }
287     Pop_2(&s,&o1);
288     printf("The Value of the Expression is %g\n",o1);
289     return OK;
290 }
291
292 int main(){
293     Queue q;
294     QueueInit(&q);
295     Infix2Postfix(&q);
296     ShowQueue(q);
297 /*
298     QueueElemtype number;
299     QueueOperatorValue operator;
300     int symbol;
301     QueueDelete(&q,&number,&operator,&symbol);
302     printf("%f,%c,%d\n",number,operator,symbol);
303 */
304     ValueExpression(q);
305 //Stack
306 /*
307     Stack s;
308     StackInit(&s);
309     StackElemtype c;
310     Push(&s,‘1‘);
311     Push(&s,‘2‘);
312     Push(&s,‘3‘);
313     Push(&s,‘4‘);
314     Pop(&s,&c);
315     printf("%c ", c);
316     Pop(&s,&c);
317     printf("%c ", c);
318     Pop(&s,&c);
319     printf("%c ", c);
320     Pop(&s,&c);
321     printf("%c ", c);
322 */
323     //Queue
324 /*
325     Queue q;
326     QueueElemtype c;
327     QueueInit(&q);
328     QueueInsert(&q,1);
329     QueueInsert(&q,2);
330     QueueInsert(&q,3);
331     QueueInsert(&q,4);
332     QueueDelete(&q,&c);
333     printf("%d ", c);
334     QueueDelete(&q,&c);
335     printf("%d ", c);
336     QueueDelete(&q,&c);
337     printf("%d ", c);
338     QueueDelete(&q,&c);
339     printf("%d ", c);
340     if(QueueDelete(&q,&c)){
341         printf("%d ",c);
342     }
343 */
344 /*
345     Queue q;
346     QueueInit(&q);
347     QueueInsert(&q,2.1);
348     QueueInsert_operatorValue(&q,‘+‘);
349     QueueInsert(&q,43.1);
350     QueueInsert_operatorValue(&q,‘a‘);
351     QueueInsert_operatorValue(&q,‘(‘);
352     int iswho;
353     double d;
354     char c;
355     QueueDelete(&q,&d,&c,&iswho);
356     if(iswho == 1)
357         printf("%f ",d);
358     else
359         printf("%c ", c);
360     QueueDelete(&q,&d,&c,&iswho);
361     if(iswho == 1)
362         printf("%f ",d);
363     else
364         printf("%c ", c);
365     QueueDelete(&q,&d,&c,&iswho);
366     if(iswho == 1)
367         printf("%f ",d);
368     else
369         printf("%c ", c);
370     QueueDelete(&q,&d,&c,&iswho);
371     if(iswho == 1)
372         printf("%f ",d);
373     else
374         printf("%c ", c);
375 */
376     return 0;
377 }

本文主要用C代码实现了求表达式的值,例如当用户输入表达式 5*((3+2)-6+8)+12/(5+3)时,可以直接得出结果为36.5.也会输出在计算过程中使用的逆波兰表达式。代码使用的数据结构主要是栈和队列,在将用户输入的中缀表达式转换为后缀表达式时,使用了栈。使用队列存储了得到的后缀表达式结构,供计算后缀表达式的值读取,在计算后缀表达式时,使用的也是栈。

程序存在的问题:1 在使用栈和队列时,如果只有存放的元素的类型不同,如一个用于存放char另一个用于存放double,那么应该怎么处理。在本程序中,分别定义了char型的栈和double型的栈,而他们除了元素的类型不同之外,其他的完全相同,这就使得本程序存在大量的冗余代码。

2 本程序中的队列中需要存放两种类型的元素,double型的操作数和char类型的操作符,所以将队列的数据域定义了两个分别来存储,并且使用了flag来表明该节点存放的是double类型的操作数还是char类型的操作符。不知是否有更好的方法

3 使用文件来保存中间生成的后缀表达式的结果,可能会使得本代码更简单

时间: 2024-10-07 05:29:43

求表达式的值--栈和队列的应用的相关文章

谁能帮帮我-栈求表达式的值

求表达式的值 下面的代码有问题,带括号的算不了,哪位大佬能帮我修复一下:我崩溃了.... #include<stdio.h> #include<stdio.h> #include <stdlib.h> typedef struct { int num[100]; int top; }Stack1; typedef struct { char num[100]; int top; }Stack2; void Init_stack1(Stack1 *s) { s->t

用递归下降分析求表达式的值

<数据结构>中表达式求值的经典算法是用两个栈,一个存数字,一个存运算符.依次读入表达式中的每个字符,若是数字则进数字栈,若是运算符则和运算符栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕.运算符的优先级表如下   + - * / ( ) # + > > < < < > > - > > < < < > > * > > > > < > > / > >

Struts2之 OGNL表达式和值栈

技术分析之OGNL表达式概述(了解)        1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写        * 所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象        * 通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能.它使用相同的表达式去存取对象的属性        2. Struts2框架使用OGNL作为默认的表达式语言 

Struts2-从值栈中获取数据-EL表达式从值栈获取

从值栈获取数据 1 使用struts2的标签+ognl表达式获取值栈数据 (1)<s:property value="ognl表达式"/> 获取字符串 原文地址:https://www.cnblogs.com/Jones-dd/p/9099552.html

3-5-表达式求值-栈和队列-第3章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第3章  栈和队列 - 表达式求值 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? SequenceStack.c        相关测试数据下载  链接? 无数据

struts2 ognl表达式访问值栈

1:简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action.Result.Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱. 简单的说,值栈能够线程安全的为每个请求提供公共的数据存取服务. 当有请求的时候,Struts2会为每个请求创建一个新的值栈,也就是说,栈和请求是一一对应的,不同的请求,值栈也不一样,而值栈封装了一次请求所有需要操作的相关的数据. 正是因为值栈和请求的对应关系,因此值栈能保证线程安全的为每个请求提供

PAT 线性结构3. 求前缀表达式的值 栈的应用

题目链接: 前缀表达式求值 题解: 同后缀表达式求值思路: 遇到数值则入栈,遇到操作符则从栈中取出最上面的两个数值进行操作,再将结果入栈,最后得到的栈顶元素则为答案. 前缀表达式从后往前遍历即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<stack> using namespace std; int op(char a) { if(a=='+'||a=='-'||a

求表达式的值

1.测试代码 public class MyClass { public static void Run() { KExpression exp = new KExpression(); string backExp = exp.GetRPN("1+3*(4+6/2)"); string value = exp.GetValue(backExp); } } 2.把计算公式转后缀表达式,去掉其中的括号 /// <summary> /// 把中缀表达式转为后缀表达式 /// &

三、StrutsOGNL表达式与值栈\视频

1.OGNL 1.1.OGZL 概述 OGNL:对象图导航语言,比 EL 表达式强大很多倍的语言. EL:从域对象中获取数据,从 EL 的11和对象中获取. 原文地址:https://www.cnblogs.com/xifengbuqi/p/9748960.html