# Data Structure - Stack and Queue and Application - Expression Evaluation

## [Experimental Purpose]

Enabling students to understand the characteristics of stacks and queues in order to use them flexibly in the context of practical problems, will also consolidate the mastery of the construction methods of these two structures and the implementation of basic operations.

## [Experimental Contents and Requirements]

1. Problem description: Implement expression evaluation.The algorithm input is an expression string and the output is the result of the expression calculation.Expression strings are required to support positive integer type operands, plus, -, /four arithmetic operators, and several function operators.For example, exp(x) means log10(x) means sqrt(x) means.Try to calculate the value of 3(sqrt(7-5)/2).
2. Basic requirements: to achieve the following requirements (1) -(3).If only the requirements (1) - (2) are met, the score is 80.
(1) Implement the basic operation of stack first, such as putting on, leaving, taking the top element of stack, etc.The implementation of the stack cannot use library functions in the compiled environment.
(2) Implement expression evaluation that supports +, -, /four arithmetic operators.
(3) Expand the support function operators on the basis of (2).
3. Tips for implementation: Assume the expression string is "#...A beta btheta c...#), where beta and theta are operators, a, b, C are operands, and the following is a table of operator precedence relationships (exp(x) functions added), other functions please join themselves. Lexical analysis method hints: Assuming the expression string is S, starting from the current position i, first get the position J of the closest operator to I (including functions), which means S[i...j-1] is an operand; if j=0, it means S[i...] is an operand.For example, for the expression string S="30sqrt(70-50)", the leftmost operator is *, and its position is 2, so the operand is S[0...1]="30".

## [Experimental Data]

```#include <iostream>
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"math.h"
#define true 1
#define false 0
#define OK 1
#define OPSETSIZE 8
using namespace std;
typedef int Status;

unsigned char Prior =
{
// Operator Priority Table
//     '+' '-' '*' '/' '(' ')' '#' '^'
/*'+'*/'>','>','<','<','<','>','>','<',
/*'-'*/'>','>','<','<','<','>','>','<',
/*'*'*/'>','>','>','>','<','>','>','<',
/*'/'*/'>','>','>','>','<','>','>','<',
/*'('*/'<','<','<','<','<','=',' ','<',
/*')'*/'>','>','>','>',' ','>','>','>',
/*'#'*/'<','<','<','<','<',' ','=','<',
/*'^'*/'>','>','>','>','<','>','>','>',
};

typedef struct StackChar
{
char c;
struct StackChar *next;
} SC;      //Node SC of StackChar type

typedef struct StackFloat
{
float f;
struct StackFloat *next;
} SF;      //Node SF of StackFloat type

SC *Push(SC *s,char c)          //SC pointer Push, returns p
{
SC *p=(SC*)malloc(sizeof(SC));
p->c=c;
p->next=s;
return p;
}

SF *Push(SF *s,float f)        //SF pointer Push, returns p
{
SF *p=(SF*)malloc(sizeof(SF));
p->f=f;
p->next=s;
return p;
}

SC *Pop(SC *s)    //Pop pointer of SC type
{
SC *q=s;
s=s->next;
free(q);
return s;
}

SF *Pop(SF *s)      //Pop pointer of SF type
{
SF *q=s;
s=s->next;
free(q);
return s;
}

float Operate(float a,unsigned char theta, float b)      //Computation function Operate
{
switch(theta)
{
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
return a/b;
case '^':
return pow(a,b);
default :
return 0;
}
}

char OPSET[OPSETSIZE]= {'+','-','*','/','(',')','#','^'};

Status In(char Test,char *TestOp)
{
int Find=false;
for (int i=0; i< OPSETSIZE; i++)
{
if(Test == TestOp[i])
Find= true;
}
return Find;
}

Status ReturnOpOrd(char op,char *TestOp)
{
for(int i=0; i< OPSETSIZE; i++)
{
if (op == TestOp[i])
return i;
}
}

char precede(char Aop, char Bop)
{
return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}

float EvaluateExpression(char* MyExpression)
{
// Operator-first algorithm for evaluating arithmetic expressions
// Set OPTR and OPND to Operator Stack and Operator Stack respectively, OP to Operator Set
SC *OPTR=NULL;       // Operator stack, character element
SF *OPND=NULL;       // Operator stack, real element
char TempData;
float Data,a,b;
char theta,*c,Dr[]= {'#','\0'};
OPTR=Push(OPTR,'#');
c=strcat(MyExpression,Dr);
strcpy(TempData,"\0");//String Copy Function
while (*c!= '#' || OPTR->c!='#')
{
if (!In(*c, OPSET))
{
Dr=*c;
strcat(TempData,Dr);           //String Connection Function
c++;
if (In(*c, OPSET))
{
Data=atof(TempData);       //String Conversion Function (double)
OPND=Push(OPND, Data);
strcpy(TempData,"\0");
}
}
else    // Stack if not an operator
{
switch (precede(OPTR->c, *c))
{
case '<': // Top stack element has low priority
OPTR=Push(OPTR, *c);
c++;
break;
case '=': // Unbracket and receive the next character
OPTR=Pop(OPTR);
c++;
break;
case '>': // Unstack and stack the result of the operation
theta=OPTR->c;
OPTR=Pop(OPTR);
b=OPND->f;
OPND=Pop(OPND);
a=OPND->f;
OPND=Pop(OPND);
OPND=Push(OPND, Operate(a, theta, b));
break;
} //switch
}
} //while
return OPND->f;
} //EvaluateExpression

int main(void)
{
char s;
cin>>s;
cout<<"The value of the expression is: "<<endl;
printf("%s\b=%g\n",s,EvaluateExpression(s));
system("pause");
return 0;
}

```

## [Experiments]   Published 7 original articles, won approval 2, visited 223

Posted on Thu, 06 Feb 2020 22:46:15 -0500 by ypirc