/*
Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,
整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,
相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2
4 + 2 * 5 - 7 / 11 0
Sample Output
3.00
13.36
*/
代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int len, top; char buf[200];
double *OPND;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char SElemType;
typedef struct {
SElemType *base; //在栈构造之前和销毁之后, base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间, 以元素为单位
}SqStack;
void InitStack(SqStack *S)
{
//构造一个空栈
S->base = (SElemType *) malloc (STACK_INIT_SIZE * sizeof(SElemType));
if (!S->base) //存储分配失败
{
printf("空间分配失败!\n");
exit(-1);
}
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
} //InitStack, 初始化空栈
char GetTop(SqStack S)
{
if (S.top == S.base)
{
printf("栈空!\n");
}
return *S.top;
} //GetTop, 获取栈顶元素
void Push(SqStack *S, SElemType e)
{
if (S->top - S->base + 1 >= S->stacksize) //栈满, 追加存储空间
{
S->base = (SElemType*)realloc(S->base,
(S->stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S->base) //存储分配失败
{
printf("空间分配失败!\n");
exit(-1);
}
S->top = S->base + S->stacksize - 1;
S->stacksize += STACKINCREMENT;
}
*++S->top = e;
} //Push
char Pop(SqStack *S)
{
//若栈不空, 则删除S的栈顶元素, 用e返回其值, 并返回OK;否则返回ERROR
if (S->top == S->base)
{
printf("栈空!\n");
}
return *S->top--;
} //Pop
char precede(char a, char b)
{
int i, j; //i, j用于判断优先级
if (a == '#') return '<';
if (a == '+' || a == '-') i = 0;
else i = 1;
if (b == '*' || b == '/') j = 1;
else j = 0;
if(i >= j) return '>';
return '<';
} //isHigher, 判断a 与 b的运算级别
char isOpnd(SElemType c)
{
if (c == '+' || c == '-' || c == '*' || c == '/')
{
return '0';
}
return '1';
} //isOpnd, 判断是否为运操作数
int main()
{
int i, j, num;
SElemType c, index;
double result, x, y;
if ((OPND=(double *)malloc(STACK_INIT_SIZE * sizeof(double))) == NULL) {
printf("空间分配失败!\n");
} //操作数栈
top = 0;
while (gets(buf), strcmp(buf, "0"))
{
SqStack OPTR;
len = strlen(buf); i = j = 0; result = 0;
InitStack(&OPTR);
Push(&OPTR, '#');
c = buf[i];
while (i < len || GetTop(OPTR) != '#')
{
if (isOpnd(c) == '1')
{
num = 0;
for(; buf[i] != ' ' && i < len; i++)
{
num = num * 10 + (buf[i]-'0');
} //获取操作数
OPND[top++] = num; //进栈
if(i < len)
{
c = buf[++i]; //获取下一字符
}
else c = '+'; //用于退出
}
else
{
switch (precede(GetTop(OPTR), c))
{
case '<': //栈顶元素优先级低
Push(&OPTR, c); i += 2;
c = buf[i];
break;
case '>': //退栈并将运算结果入操作数栈
index = Pop(&OPTR);
x = OPND[--top]; y = OPND[--top];
if (index == '+')
{
result = x + y;
}
else if (index == '-')
{
result = y - x;
}
else if (index == '*')
{
result = x * y;
}
else
{
result = y * 1.0 / x;
}
OPND[top++] = result;
break;
}
}
}
printf("%.2lf\n", OPND[--top]);
}
return 0;
}