使用栈实现表达式求值
题目要求
读取一个多项式,使用栈进行多项式求值,并输出结果。
##思路
1.使用两个栈,nums用于存储操作数,ops用于存储操作符
2.从左往右扫描,遇到操作数入栈nums
3.遇到操作符时,如果优先级低于或等于栈顶操作符优先级,则从nums弹出两个元素进行计算,并压入nums,
继续与栈顶操作符的比较优先级
4.如果遇到操作符高于栈顶操作符优先级,则直接入栈ops
5.遇到左括号,直接入栈ops,遇到右括号,则直接出栈并计算,直到遇到左括号
#include<bits/stdc++.h>//万能头文件,没有的话需要手动下载
typedef int datatype;
#define maxsize 64
//定义顺序栈结构
struct seqstack
{
datatype data[maxsize];
int top;
};
//定义基本函数
seqstack* CREATES()
{
seqstack* p;
p = (seqstack*)malloc(sizeof(seqstack));
p->top = -1;
return p;
}
seqstack* SETNULL(seqstack* S)
{
S->top = -1;
}
int EMPTY(seqstack* S)
{
if (S->top >= 0)
return false;
else
return true;
}
seqstack* PUSH(seqstack* s, datatype x)
{
if (s->top == maxsize - 1)
{
printf("overflow");
return NULL;
}
else
{
s->top++;
s->data[s->top] = x;
}
return s;
}
datatype POP(seqstack* s)
{
if (EMPTY(s))
{
printf("underflow");
return NULL;
}
else
{
s ->top--;
return s->data[s->top + 1];
}
}
datatype TOP(seqstack* s)
{
if (EMPTY(s))
{
printf("underflow");
return NULL;
}
else
{
return s->data[s->top];
}
}
//记录运算符号优先级
static char pre[128] = { 0 };
//定义优先级
void setpre()
{
pre['+'] = 4;
pre['-'] = 4;
pre['*'] = 3;
pre['/'] = 3;
pre['('] = 1;
pre[')'] = 1;
}
//创建字符串接收字符串型数据
string gets()
{
string s;
cin >> s ;
return s;
}
//比较两个符号的优先级,如果op2高于op1则返回fu值,相等为0,低于为z值
int precompare(char op1, char op2)
{
return pre[op2] -pre[ op1];
}
//计算操作,只负责计算,将所得数据压入num中;
int active(seqstack* num, seqstack* ops)
{
int a, b, r=0,op;
op=POP(ops);
if (op == '(')
op = POP(ops);
b = POP(num);
a = POP(num);
printf("get b from stack %d\n", b);
printf("get a from stack %d\n", a);
printf("get op from stack %c\n", op);
switch (op)
{
case '+':
{
printf("push %d into stack\n", a + b);
r=a+b;
PUSH(num, r);
break;
}
case '-':
{
printf("push %d into stack\n", a - b);
r=a-b;
PUSH(num, r);
break;
}
case '*':
{
printf("push %d into stack\n", a * b);
r = a * b;
PUSH(num, r);
break;
}
case '/':
{
printf("push %d into stack\n", a / b);
r=a/b;
PUSH(num, r);
break;
}
}
return r;
}
//整体操作,进行运算,得出结果
int addition(string str)
{
cout << str << endl;
int i=0, j, k, flag, temp;
//创建两个栈,nums装填数字,ops装填操作符
seqstack* nums, * ops;
nums = CREATES();
ops = CREATES();
while (str[i] != '#')//遍历多项式
{
cout << str[i]<<" ";
if (str[i] >= '0' && str[i] <= '9')//判断是否为数字
{
if (flag == 1)//判断前一个字符是否为数字,如果是,弹出乘10加下一位
{
temp = POP(nums);
}
else
temp = 0;
temp = temp * 10 + str[i] - '0';
flag = 1;
PUSH(nums, temp);
}
//判断是否为操作符,如果是则进行判断和计算
else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
{
flag = 0;
if (ops->top<0)//判断操作数栈是否为空栈,是则直接插入,不是则判断是否需要运算
{
PUSH(ops, str[i]);
}
else
{
if (precompare(TOP(ops),str[i])>=0)//如果新输入的符号优先级低于之前的,进行计算
{
if (TOP(ops) == '(')
PUSH(ops, str[i]);
else
{
active(nums, ops);
PUSH(ops, str[i]);
}
}
else
{
PUSH(ops, str[i]);
}
}
}
else if (str[i] == '(')//左括号直接压入
{
flag = 0;
PUSH(ops, str[i]);
}
else if (str[i] == ')')//右括号对左侧进行弹出计算
{
flag = 0;
while (TOP(ops) !='(')//遍历到左括号结束
{
if (TOP(ops) == '(')
{
POP(ops);
break;
}
active(nums, ops);
printf("%c\n", TOP(ops));
}
}
i++;
}
while (!EMPTY(nums) && !EMPTY(ops))//判断是否计算完全,即操作数栈为空
{
active(nums, ops);
}
temp = POP(nums);
printf("%d\n", temp);
return 0;
}
int main()
{
string s;
setpre();
//freopen("D:\\学习X\\数据结构\\基础操作实现\\text.in", "r", stdin);
s = gets();
addition(s);
return 0;
}