/**
*
* Author:HackerHao
* Create:2023.09.27
*
*/
#include <bits/stdc++.h>
using namespace std;
#define ElemType int
#define MAXSIZE 200
typedef struct
{
ElemType data[MAXSIZE]; //数据域
int top; //栈顶"指针"
}SqStack;
SqStack* Create(void) //创建栈,将top初始化为-1
{
SqStack* k = (SqStack*)malloc(sizeof(SqStack));
k->top = -1;
return(k);
}
bool Push(SqStack* p, ElemType n) //进栈
{
//进栈先判断栈满!!!
if (p->top == MAXSIZE - 1)
return(false);
p->data[++p->top] = n;
return(true);
}
ElemType Pop(SqStack* p) //出栈
{
//出栈先判断栈空!!!
if (p->top == -1)
return(-1); //返回-1表示出栈失败
return(p->data[p->top--]);
}
ElemType Top(SqStack* p) //获取栈顶元素
{
//获取栈顶元素也要判断栈空!!!
if (p->top == -1)
return(-1); //返回-1表示取值失败
return(p->data[p->top]); //直接返回栈顶元素
}
ElemType Expression(char* s)
{
SqStack* Optr, * Oper;
ElemType d, result;
bool Calculate(SqStack * Oper, SqStack * Optr);
Optr = Create(); //运算符栈
Push(Optr, '#'); //字符#先压入栈中
Oper = Create(); //操作数栈
while (*s != '\0')
{
if (*s >= '0' && *s <= '9')
{
d = 0;
while (*s >= '0' && *s <= '9') //用一个循环来计算连续的数字字符组成的值
{
d = 10 * d + *s - '0';
s++;
}
s--; //跳出循环,s指向数字字符的后面字符,为了同步,再--,否则将会跳过读取一个字符
//将求的值压入Oper栈中
Push(Oper, d);
}
else
{
if (*s == '(' || *s == '*' || *s == '/')
Push(Optr, *s); //乘和除优先级最高,(左括号,都直接进操作符栈
else if (*s == ')')
{
while (Top(Optr) != '(') //没到左括号,一直计算
Calculate(Oper, Optr);
Pop(Optr); //左括号出栈
}
else if (*s == '#')
{
while (Top(Optr) != '#') //还剩有计算没做,继续运算
Calculate(Oper, Optr);
break;
}
else if (*s == '+' || *s == '-')
{
char TopElement = Top(Optr); //取运算符栈顶操作符,与读取的操作符比较优先级
switch (TopElement)
{
case '+':
case '-':
case '(':
case '#':
Push(Optr, *s);
break; //栈顶元素优先级低,直接将所读操作符入栈,读取下一个
case '*':
case '/': //栈顶元素优先级高,则进行“计算并且压入”操作
do {
Calculate(Oper, Optr); //先做一次计算
TopElement = Top(Optr); //取新的栈顶运算符
} while (TopElement == '*' || TopElement == '/'); //栈顶元素优先级高则继续计算,直到栈顶元素优先级低,
//到栈顶元素优先级低,压入读取元素
Push(Optr, *s);
break;
}
}
else
{
printf("error!");
exit(0);
}
}
s++;
}
result = Top(Oper); //操作数栈顶元素即所求结果
free(Oper);
free(Optr); //操作数栈和运算符栈释放掉
return result;
}
//计算函数: 操作数栈中出2个数和运算符栈中出1个操作符做计算,结果压入操作数栈中
bool Calculate(SqStack* Oper, SqStack* Optr)
{
ElemType a, b, result;
char k = Pop(Optr); //运算符栈中出一个运算符
a = Pop(Oper);
b = Pop(Oper); //操作数栈中出两个数
switch (k)
{
case '+':
result = b + a; break;
case '-':
result = b - a; break;
case '*':
result = b * a; break;
case '/':
if (a == 0)
{
printf("除数不能为 0 !!"); //输出错误信息后终止程序
exit(0); //该函数在 stdlib.h 的头文件中,与malloc等函数一样
}
else
result = b / a;
break;
}
Push(Oper, result); //结果压入Oper操作数栈中
return true;
}
int main(void)
{
bool Push(SqStack * p, ElemType n);
ElemType Pop(SqStack * p); //出栈,函数类型是栈元素数据类型
ElemType Top(SqStack * p); //获取栈顶元素,注意函数返回类型也是栈元素数据类型
ElemType Expression(char* s); //求s指向字符串算术表达式的值
char str[MAXSIZE];
ElemType result;
cout << "请输入表达式:(注意:不要输入空格,且输入完成后用#结束)" << endl;
cin >> str;
result = Expression(str);
cout <<"最终结果为:" << result << endl;
return(0);
}