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

 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 使用文件来保存中间生成的后缀表达式的结果,可能会使得本代码更简单
相关文章
相关标签/搜索