求表達式的值--棧和隊列的應用

 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 使用文件來保存中間生成的後綴表達式的結果,可能會使得本代碼更簡單
相關文章
相關標籤/搜索