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