数据结构(C语言版)---第三章栈和队列 3.3 表达式求值
主要是参照“算法优先法”改写的。如何判断两个算术运算符之间的优先关系值得借鉴。
源码如下:
Main_3_3_EvaluateExpression.c
#include "Stack_char.h" #include "Stack_float.h" #define OPSETSIZE 7 unsigned char Prior[7][7] = { // ±í3.1 Ëã·û¼äµÄÓÅÏȹØϵ '>','>','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','>','>','<','>','>', '>','>','>','>','<','>','>', '<','<','<','<','<','=',' ', '>','>','>','>',' ','>','>', '<','<','<','<','<',' ','=' }; float Operate(float a, unsigned char theta, float b); char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; int In(char Test,char* TestOp); char precede(char Aop, char Bop); typedef int bool; float EvaluateExpression(char* MyExpression) { // Ëã·¨3.4 // ËãÊõ±í´ïʽÇóÖµµÄËã·ûÓÅÏÈËã·¨¡£ // ÉèOPTRºÍOPND·Ö±ðΪÔËËã·ûÕ»ºÍÔËËãÊýÕ»£¬OPΪÔËËã·û¼¯ºÏ¡£ PCharStack OPTR; // ÔËËã·ûÕ»£¬×Ö·ûÔªËØ PFloatStack OPND; // ÔËËãÊýÕ»£¬ÊµÊýÔªËØ char TempData[20]; float Data,a,b; char theta,*c,x,Dr[2]; OPTR = (PCharStack)malloc(sizeof(CharStack)); OPND = (PFloatStack)malloc(sizeof(FloatStack)); printf("src: %s\n",MyExpression); InitCharStack (OPTR); PushChar(OPTR, '#'); InitFloatStack (OPND); c = MyExpression; strcpy(TempData,"\0"); while (*c!= '#' || GetTopChar(OPTR,&theta)!= '#') { if (!In(*c, OPSET)) { Dr[0]=*c; Dr[1]='\0'; strcat(TempData,Dr); c++; if(In(*c,OPSET)) { Data=(float)atof(TempData); PushFloat(OPND, Data); strcpy(TempData,"\0"); } } else { // ²»ÊÇÔËËã·ûÔò½øÕ» switch (precede(GetTopChar(OPTR,&theta), *c)) { case '<': // Õ»¶¥ÔªËØÓÅÏÈȨµÍ PushChar(OPTR, *c); c++; break; case '=': // ÍÑÀ¨ºÅ²¢½ÓÊÕÏÂÒ»×Ö·û PopChar(OPTR, &theta); c++; break; case '>': // ÍËÕ»²¢½«ÔËËã½á¹ûÈëÕ» PopChar(OPTR, &theta); PopFloat(OPND, &b); PopFloat(OPND, &a); PushFloat(OPND, Operate(a, theta, b)); break; } // switch } } // while Data = GetTopFloat(OPND,&Data); DestoryCharStack(OPTR); DestoryFloatStack(OPND); free(OPTR); free(OPND); return Data; } // EvaluateExpression float Operate(float a,unsigned char theta, float b) { switch(theta) { case '+': return a+b; case '-': return a-b; case '*': return a*b; case '/': return a/b; default : return 0; } } int In(char Test,char* TestOp) { int Find = 0; int i ; for (i=0; i< OPSETSIZE; i++) { if (Test == TestOp[i]) Find= 1; } return Find; } int ReturnOpOrd(char op,char* TestOp) { int i; for(i=0; i< OPSETSIZE; i++) { if (op == TestOp[i]) return i; } return 0; } char precede(char Aop, char Bop) { return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)]; } int main(int argc, char **argv) { printf("please input your expression :\n"); char MyExpression[124]; fgets(MyExpression,sizeof(MyExpression),stdin); strcat(MyExpression,"#"); printf("result is : %f\n",EvaluateExpression( MyExpression)); return 0; }
Stack_char.h:
#ifndef _STACK_CHAR_H #define _STACK_CHAR_H #include <stdlib.h> #include <string.h> #include <stdio.h> #define STACK_INIT_SIZE 100 #define STACK_INCRE_SIZE 50 typedef char SElemTypeChar ; typedef struct SqCharStack { SElemTypeChar *base; SElemTypeChar *top; int stackSize; }CharStack,*PCharStack; int InitCharStack(PCharStack S); int GetCharTop(PCharStack S,SElemTypeChar *e); int PushChar(PCharStack S,SElemTypeChar e); int PopChar(PCharStack S,SElemTypeChar *e); int ClearCharStack(PCharStack S); int DestoryCharStack(PCharStack S); void PrintCharStack(PCharStack S); int IsCharStackEmpty(PCharStack S); #endif
Stack_char.c:
#include "Stack_char.h" /*3.1 3.2*/ int InitCharStack(PCharStack S) { S->base = (SElemTypeChar *)malloc(sizeof(SElemTypeChar) * STACK_INIT_SIZE); if(!S->base) { exit(0); } S->top = S->base; S->stackSize = STACK_INIT_SIZE; return 1; } int GetTopChar(PCharStack S,SElemTypeChar *e) { if(S->base == S->top) { return -1; } *e = *(S->top -1); return *e; } int PushChar(PCharStack S,SElemTypeChar e) { if(S->top - S->base >= S->stackSize) { S->base = (SElemTypeChar *)realloc(S->base,(S->stackSize + STACK_INCRE_SIZE) * sizeof(SElemTypeChar)); if(!S->base) { return -1; } S->top = S->base + S->stackSize; S->stackSize += STACK_INCRE_SIZE; } *S->top++ = e; return 1; } int PopChar(PCharStack S,SElemTypeChar *e) { if(S->base == S->top) { return -1; } *e = * -- S->top; } int ClearCharStack(PCharStack S) { S->top = S->base; return 1; } int DestoryCharStack(PCharStack S) { free(S->base); } void PrintCharStack(PCharStack S) { PCharStack p; p = S; int i = 0; while(p->top != p->base) { i++; printf("%c\t",* -- p->top); if((i != 0) && (i % 10 == 0)) { printf("\n\t\t\t"); } } p->top += i; printf("\n"); } int IsCharStackEmpty(PCharStack S) { return ((S->base == S->top) ? 1 : 0); }
Stack_float.h:
#ifndef _STACK_FLOAT_H #define _STACK_FLOAT_H #include <stdlib.h> #include <string.h> #include <stdio.h> #define STACK_INIT_SIZE 100 #define STACK_INCRE_SIZE 50 typedef float SElemTypeFloat ; typedef struct SqFloatStack { SElemTypeFloat *base; SElemTypeFloat *top; int stackSize; }FloatStack,*PFloatStack; int InitFloatStack(PFloatStack S); int GetTopFloat(PFloatStack S,SElemTypeFloat *e); int PushFloat(PFloatStack S,SElemTypeFloat e); int PopFloat(PFloatStack S,SElemTypeFloat *e); int ClearFloatStack(PFloatStack S); int DestoryFloatStack(PFloatStack S); void PrintFloatStack(PFloatStack S); int IsFloatStackEmpty(PFloatStack S); #endif
Stack_float.c:
#include "Stack_float.h" /*3.1 3.2*/ int InitFloatStack(PFloatStack S) { S->base = (SElemTypeFloat *)malloc(sizeof(SElemTypeFloat) * STACK_INIT_SIZE); if(!S->base) { exit(0); } S->top = S->base; S->stackSize = STACK_INIT_SIZE; return 1; } int GetTopFloat(PFloatStack S,SElemTypeFloat *e) { if(S->base == S->top) { return -1; } *e = *(S->top -1); return *e; } int PushFloat(PFloatStack S,SElemTypeFloat e) { if(S->top - S->base >= S->stackSize) { S->base = (SElemTypeFloat *)realloc(S->base,(S->stackSize + STACK_INCRE_SIZE) * sizeof(SElemTypeFloat)); if(!S->base) { return -1; } S->top = S->base + S->stackSize; S->stackSize += STACK_INCRE_SIZE; } *S->top++ = e; return 1; } int PopFloat(PFloatStack S,SElemTypeFloat *e) { if(S->base == S->top) { return -1; } *e = * -- S->top; } int ClearFloatStack(PFloatStack S) { S->top = S->base; return 1; } int DestoryFloatStack(PFloatStack S) { free(S->base); } void PrintFloatStack(PFloatStack S) { PFloatStack p; p = S; int i = 0; while(p->top != p->base) { i++; printf("%f\t",* -- p->top); } p->top += i; printf("\n"); } int IsFloatStackEmpty(PFloatStack S) { return ((S->base == S->top) ? 1 : 0); }
运行结果如下:
please input your expression : 56+89*45-90/3 src: 56+89*45-90/3 # get top # 35 get top + 43 get top * 42 get top + 43 get top # 35 get top - 45 get top / 47 get top / 47 get top - 45 get top - 45 get top # 35 result is : 4031.000000