#ifndef _GLOBAL_VAR_H
#define _GLOBAL_VAR_H
#include <stdlib.h>
#include <stdio.h>
typedef char INT8;
typedef unsigned char UINT8;
typedef int INT32;
typedef unsigned int UINT32;
#define E_SUCCESS (INT32)1
#define E_FAIL (INT32)-1
#define E_STACK_EMPTY (INT32)1
#define E_STACK_NOT_EMPTY (INT32)0
#define E_IS_OPERATOR (INT32)1
#define E_IS_NOT_OPERATOR (INT32)0
#define E_IS_NUM (INT32)1
#define E_IS_NOT_NUM (INT32)0
#define E_HIGH_PRIORITY (INT32)3
#define E_NORMAL_PRIORITY (INT32)2
#define E_LOW_PRIORITY (INT32)1
struct s_node
{
INT32 iData;
struct s_node *pstNext;
};
typedef struct s_node T_Node;
T_Node *NodePush(T_Node *pstStack,INT32 iValue);
T_Node *NodePop(T_Node *pstStack,INT32 * piValue);
INT32 StackEmptyChk(T_Node *pstStack);
INT32 OperatorChk(INT8 cOperator);
INT32 OperandChk(INT8 cOperand);
INT32 GetPriority(INT8 cOperator);
INT32 Caculate(INT8 cOperator,INT32 iOperand1,INT32 iOperand2);
#endif
#include "globalvar.h"
T_Node *NodePush(T_Node *pstStack,INT32 iValue)
{
INT8 acLogHead[] = "NodePush";
T_Node *pstNewNode = NULL;
pstNewNode = (T_Node *)malloc(sizeof(T_Node));
if ( NULL == pstNewNode )
{
printf("%s: Memory allocate fail!/n",acLogHead);
return NULL;
}
pstNewNode->iData = iValue;
pstNewNode->pstNext = pstStack;
pstStack = pstNewNode;
return pstStack;
}
T_Node *NodePop(T_Node *pstStack,INT32 * piValue)
{
INT8 acLogHead[] = "NodePop";
T_Node *pstNodeTop;
if ( NULL == pstStack || NULL == piValue)
{
printf("%s: input param wrong!/n",acLogHead);
return NULL;
}
if ( NULL != pstStack )
{
pstNodeTop = pstStack;
pstStack = pstStack->pstNext;
*piValue = pstNodeTop->iData;
free(pstNodeTop);
}
return pstStack;
}
INT32 StackEmptyChk(T_Node *pstStack)
{
if ( NULL == pstStack )
{
return E_STACK_EMPTY;
}
else
{
return E_STACK_NOT_EMPTY;
}
}
INT32 OperatorChk(INT8 cOperator)
{
INT32 iResult = 0;
switch (cOperator)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
iResult = E_IS_OPERATOR;
break;
default:
iResult = E_IS_NOT_OPERATOR;
break;
}
return iResult;
}
INT32 OperandChk(INT8 cOperand)
{
INT32 iResult = 0;
if ( cOperand >= '0' && cOperand <= '9' )
{
iResult = E_IS_NUM;
}
else
{
iResult = E_IS_NOT_NUM;
}
return iResult;
}
INT32 GetPriority(INT8 cOperator)
{
INT8 acLogHead[] = "GetPriority";
INT32 iPriority = 0;
switch (cOperator)
{
case '+':
case '-':
iPriority = E_LOW_PRIORITY;
break;
case '*':
case '/':
iPriority = E_NORMAL_PRIORITY;
break;
case '(':
case ')':
iPriority = E_HIGH_PRIORITY;
break;
default:
printf("%s: input param wrong!/n",acLogHead);
iPriority = E_FAIL;
break;
}
return iPriority;
}
INT32 Caculate(INT8 cOperator,INT32 iOperand1,INT32 iOperand2)
{
INT8 acLogHead[] = "Caculate";
INT32 iResult = 0;
switch (cOperator)
{
case '+':
iResult = iOperand2 + iOperand1;
break;
case '-':
iResult = iOperand2 - iOperand1;
break;
case '*':
iResult = iOperand2 * iOperand1;
break;
case '/':
if ( 0 == iOperand1 )
{
printf("%s: Param1 must not be 0!/n",acLogHead);
iResult = E_FAIL;
}
else
{
iResult = iOperand2 / iOperand1;
}
break;
default:
printf("%s: operator is wrong!/n",acLogHead);
iResult = E_FAIL;
break;
}
return iResult;
}
#ifndef _COUNT_H
#define _COUNT_H
#include "../global/globalvar.h"
INT32 ExpressionCaculate(INT8 *pcExpress);
#endif
#include "count.h"
INT32 ExpressionCaculate(INT8 *pcExpress)
{
INT8 acLogHead[] = "ExpressionCaculate";
T_Node *pstOperator = NULL;
T_Node *pstOperand = NULL;
UINT32 uiPosition = 0;
INT8 iOperator = 0;
INT32 iOperand1 = 0;
INT32 iOperand2 = 0;
INT32 iResult = 0;
INT32 iBracket = 0;
if ( NULL == pcExpress )
{
printf("%s: input param wrong!/n",acLogHead);
return E_FAIL;
}
//进行空格裁剪
while (pcExpress[uiPosition] != '/0' && pcExpress[uiPosition] != '/n')
{
if ( E_IS_OPERATOR == OperatorChk(pcExpress[uiPosition]) )
{
if ( E_STACK_EMPTY == StackEmptyChk(pstOperator) )
{
pstOperator = NodePush(pstOperator,pcExpress[uiPosition]);
}
else
{
while ( E_STACK_EMPTY != StackEmptyChk(pstOperator) )
{
if ( '(' == pcExpress[uiPosition] )
{
iBracket++;
break;
}
else if ( ')' == pcExpress[uiPosition] )
{
pstOperator = NodePop(pstOperator,&iOperator);
while ( '(' != iOperator )
{
pstOperand = NodePop(pstOperand,&iOperand1);
pstOperand = NodePop(pstOperand,&iOperand2);
iResult = Caculate(iOperator,iOperand1,iOperand2);
pstOperand = NodePush(pstOperand,iResult);
pstOperator = NodePop(pstOperator,&iOperator);
}
break;
}
else if ( GetPriority(pcExpress[uiPosition]) <= GetPriority(pstOperator->iData) && ('(' != pstOperator->iData) )
{
pstOperand = NodePop(pstOperand,&iOperand1);
pstOperand = NodePop(pstOperand,&iOperand2);
pstOperator = NodePop(pstOperator,&iOperator);
iResult = Caculate(iOperator,iOperand1,iOperand2);
pstOperand = NodePush(pstOperand,iResult);
}
else
{
break;
}
}
if ( ')' != pcExpress[uiPosition])
{
pstOperator = NodePush(pstOperator,pcExpress[uiPosition]);
}
}
}
else if ( E_IS_NUM == OperandChk(pcExpress[uiPosition]) )
{
pstOperand = NodePush(pstOperand,pcExpress[uiPosition]-48);
}
else
{
printf("%s: input expression is wrong!/n",acLogHead);
return E_FAIL;
}
uiPosition++;
}
while ( E_STACK_EMPTY != StackEmptyChk(pstOperator) )
{
pstOperand = NodePop(pstOperand,&iOperand1);
pstOperand = NodePop(pstOperand,&iOperand2);
pstOperator = NodePop(pstOperator,&iOperator);
iResult = Caculate(iOperator,iOperand1,iOperand2);
pstOperand = NodePush(pstOperand,iResult);
}
pstOperand = NodePop(pstOperand,&iResult);
return iResult;
}
#include "../global/globalvar.h"
#include "../count/count.h"
INT32 main(void)
{
INT8 acExpress[100] = {0};
INT32 iResult = 0;
printf("Please input the expression:");
gets(acExpress);
printf("/n");
iResult = ExpressionCaculate(acExpress);
printf("the expression [%s] result is '%d'/n",acExpress,iResult);
return 0;
}