数据结构(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

作者: TigerXiao

Email: tiger.xiaowh001@gmail.com

出处: 老虎工作室

说明: 欢迎讨论、转载,转载请注明出处。

原文地址:https://www.cnblogs.com/xiaowenhu/p/3135719.html