/*8588 表达式求值
时间限制:1000MS 代码长度限制:10KB
提交次数:3462 通过次数:1255
题型: 编程题 语言: G++;GCC
Description
顺序栈的基本操作如下:
利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。要求输出表达式的值(两运算符号的优先关系见教材表3.1)。
输入格式
第一行:一个算术表达式
输出格式
第一行:算术表达式的值
输入样例
3*(9-7)=
输出样例
6
若 ch 是数字,直接压入操作数栈OPND;
若 ch 是'(',直接入栈OPTR;若 ch 是')',若OPTR 和 OPND 非空,弹出OPTR的栈顶操作符,弹出OPND栈顶的两个操作数,做运算,然后见个结果压入栈OPND,直到弹出的OPTR栈顶元素时')';
若 ch 是操作符(比如+, -, *, /),如果OPTR栈顶元素是 (,直接入栈OPTR,如果不是'('且OPTR栈非空且栈顶元素操作符的优先级大于ch,那么弹出OPTR的栈顶操作符,并弹出OPND中栈顶的两个元素,做运算,将运算结果入栈OPND,此时,重复这一步操作;否则将ch入栈OPTR;
*/
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
#include <ctype.h>
#include <string.h>
typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S)
{
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!S.base)
return ERROR;
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status Push(SqStack &S, SElemType e)
{
// 在栈S中插入元素e为新的栈顶元素
if (S.top - S.base >= S.stacksize)
{
S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S.base)
return ERROR;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return OK;
}
Status Pop(SqStack &S, SElemType &e)
{
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if (S.top == S.base)
return ERROR;
e = *--S.top;
return OK;
}
Status GetTop(SqStack S, SElemType &e)
{
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if (S.top == S.base)
return ERROR;
e = *(S.top - 1);
return OK;
}
int StackLength(SqStack S)
{
// 返回栈S的元素个数
int i;
i = S.top - S.base;
return i;
}
Status StackTraverse(SqStack S)
{
// 从栈顶到栈底依次输出栈中的每个元素
SElemType *p = (SElemType *)malloc(sizeof(SElemType));
p = S.top;
if (S.top == S.base)
printf("The Stack is Empty!");
else
{
printf("The Stack is: ");
p--;
while (p >= S.base)
{
printf("%d ", *p);
p--;
}
}
printf("\n");
return OK;
}
int reuslt(int num1, int num2, int optr)
{
switch (optr)
{
case '+':
return num1 + num2;
case '*':
return num1 * num2;
case '/':
return num2 / num1;
case '-':
return num2 - num1;
}
}
int main()
{
SqStack S1;
InitStack(S1);
SqStack S2;
InitStack(S2);
char s[100];
gets(s);
int topS2;
int topS1 = 0;
int num1, num2;
int optr;
for (int i = 0; s[i] != '='; i++)
{
if (isdigit(s[i]))
{
if (i!=0&&isdigit(s[i - 1])) {
Pop(S1, topS1);
Push(S1, topS1 * 10 + (s[i] - '0')); //这个是为了处理出现连续输入多位数字的情况
}
else
{
Push(S1, (s[i] - '0'));
}
}
else
{
switch (s[i])
{
case '(':
Push(S2, s[i]);
break;
case ')':
if (StackLength(S1) != 0 && StackLength(S2) != 0)
{
for (Pop(S2, optr); optr != '('; Pop(S2, optr))
{
Pop(S1, num1);
Pop(S1, num2);
Push(S1, reuslt(num1, num2, optr));
}
break;
}
case '+':
GetTop(S2, optr);
if (StackLength(S2) == 0 || optr == '(' )
{
Push(S2, s[i]);
break;
}
else if (optr == '*' || optr == '/' || optr == '+'|| optr == '-')
{
Pop(S1, num1);
Pop(S1, num2);
Pop(S2, optr);
Push(S1, reuslt(num1, num2, optr));
Push(S2, '+');//前两个弹出来了 运算符还是要入栈的
break;
}
case '-':
GetTop(S2, optr);
if (StackLength(S2) == 0 || optr == '(' )
{
Push(S2, s[i]);
break;
}
else if (optr == '*' || optr == '/' || optr == '-'|| optr == '+')
{
Pop(S1, num1);
Pop(S1, num2);
Pop(S2, optr);
Push(S1, reuslt(num1, num2, optr));
Push(S2, '-');//前两个弹出来了 运算符还是要入栈的
break;
}
case '*':
GetTop(S2, optr);
if (StackLength(S2) == 0 || optr == '(' || optr == '-'|| optr == '+')
{
Push(S2, s[i]);
break;
}
else if (optr == '*' || optr == '/' )
{
Pop(S1, num1);
Pop(S1, num2);
Pop(S2, optr);
Push(S1, reuslt(num1, num2, optr));
Push(S2, '*');//前两个弹出来了 运算符还是要入栈的
break;
}
break;
case '/':
GetTop(S2, optr);
if (StackLength(S2) == 0 || optr == '(' || optr == '-'|| optr == '+')
{
Push(S2, s[i]);
break;
}
else if (optr == '*' || optr == '/' )
{
Pop(S1, num1);
Pop(S1, num2);
Pop(S2, optr);
Push(S1, reuslt(num1, num2, optr));
Push(S2, '/');//前两个弹出来了 运算符还是要入栈的
break;
}
break;
break;
}
}
}
while (StackLength(S2) != 0)
{
Pop(S1, num1);
Pop(S1, num2);
Pop(S2, optr);
Push(S1, reuslt(num1, num2, optr));
}
int sum = 0;
GetTop(S1, sum);
printf("%d", sum);
}