#include
#include
#include
#include
#include
#define MaxSize 100
//定义栈结构,用于存储数据和符号
typedef struct
{
char num[MaxSize];
int top;
}Stack, * PSTACK;
//出栈
char pop(PSTACK L)
{
if (L->top == 0)
{
return 0;
}
char temp = L->num[--L->top];
return temp;
};
//入栈
char push(PSTACK L, char e)
{
if (L->top == MaxSize - 1)
{
return 0;
}
L->num[L->top++] = e;
return e;
};
//两个数的四则运算
int count(int num1, int num2, char sym, int result)
{
switch(sym)
{
case '+' :
result = num1 + num2;
break;
case '-' :
result = num1 - num2;
break;
case '*' :
result = num1 * num2;
break;
case '/' :
result = num1 / num2;
break;
default :
printf("error\n");
}
return result;
}
//判断当前是否可以进行运算
bool getPriority(char nextSymbol, PSTACK L)
{
char symbol1 = L->num[L->top - 1];
char symbol2 = nextSymbol;
if (L->top == 0)
return false;
if (nextSymbol == '\0')
return true;
if (nextSymbol == '(')
return false;
if (nextSymbol == ')')
return true;
if ((symbol1 == '+' || symbol1 == '-') && (symbol2 == '+' || symbol2 == '-'))
return true;
if ((symbol1 == '*' || symbol1 == '/') && (symbol2 == '*' || symbol2 == '/'))
return true;
if ((symbol1 == '*' || symbol1 == '/') && (symbol2 == '+' || symbol2 == '-'))
return true;
return false;
}
//执行运算的主函数
int calc(const char *expr)
{
int i = 0;
Stack g_SData, g_SSymbol;
int result = 0;
int num1 = 0, num2 = 0;
char sym;
bool priority = false;
for (i = 0; i < strlen(expr); i++)
{
//压入数据和符号
if (*(expr + i) >= 48 && *(expr + i) <= 57)
{
push(&g_SData, *(expr + i));
}
else
{
if (*(expr + i) != ')')
push(&g_SSymbol, *(expr + i));
}
//判断当前是否可以进行运算
priority = getPriority(*(expr + i + 1), &g_SSymbol);
//进行运算
while (g_SData.top >= 2 && g_SSymbol.top >= 1 && priority == true)
{
num2 = (int) (pop(&g_SData) - '0');
num1 = (int) (pop(&g_SData) - '0');
sym = pop(&g_SSymbol);
while (g_SSymbol.num[g_SSymbol.top - 1] == '(') pop(&g_SSymbol);
result = count(num1, num2, sym, result);
push(&g_SData, result + 48);
priority = getPriority(*(expr + i + 1), &g_SSymbol);
}
}
//返回计算结果
return result;
}
int main()
{
assert(calc("9+2*3*4/6-5/5") == 12);
assert(calc("(3+2)*((3+9)/3)") == 20);
return 0;
}