/*
* Created by Microsoft Visual Studio 2013
* @author: Teresa
* @date: 2017-10-07
* @description: 表达式求值
*/
#include
#include
/*函数状态码*/
#define TRUE 1 //成功
#define OK 1
#define FALSE 0 //失败
#define ERROR 0 //错误
#define INFEASIBLE -1 //不可行的
#define OVERFLOW -2 //溢出
#define STACK_INIT_SIZE 100 //存储空间初试分配量
#define STACKINCREMENT 10 //存储空间分配增量
typedef double OpndType; // 操作数栈存放的数据类型
typedef char OptrType; // 操作符栈存放的数据类型
typedef int Status; //函数的返回值类型
/*操作符栈*/
typedef struct{
OptrType *base; //栈底指针,始终指向栈底,如果为null说明栈不存在
OptrType *top; //栈顶指针,当top == base时,为空栈;
int stackSize; //当前已分配的存储空间,以元素为单位
}OptrStack;
//top-base为当前栈中的元素个数
/*操作数栈*/
typedef struct{
OpndType *base;
OpndType *top;
int stackSize;
}OpndStack;
/*操作符栈操作*/
//构造一个空栈
Status InitOptrStack(OptrStack &S){
S.base = (OptrType *)malloc(STACK_INIT_SIZE*sizeof(OptrType));
if (!S.base)
exit(ERROR);
S.top = S.base; //栈顶指向栈底
S.stackSize = STACK_INIT_SIZE;
return OK;
}
//判断S是否为空栈
Status OptrStackEmpty(OptrStack &S){
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
//若栈不为空 则e返回S的栈顶元素 并返回OK 否则ERROR
Status GetOptrTop(OptrStack S, OptrType &e){
if (S.top > S.base){
e = *(S.top - 1);
return OK;
}
else
return ERROR;
}
//插入e为新的栈顶元素
Status OptrPush(OptrStack &S, OptrType e){
if (S.top - S.base == S.stackSize){
//栈满 追加存储空间
S.base = (OptrType*)realloc(S.base, (S.stackSize + STACKINCREMENT)*sizeof(OptrType));
if (!S.base)
exit(ERROR);
S.top = S.base + S.stackSize; //修改栈顶指针
S.stackSize += STACKINCREMENT; //更新容量
}
*(S.top++) = e;
return OK;
}
//若栈不为空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERROR
Status OptrPop(OptrStack &S, OptrType &e){
if (S.top == S.base) return ERROR;
e = *--S.top;
return OK;
}
/*操作数栈操作*/
//构造一个空栈
Status InitOpndStack(OpndStack &S){
S.base = (OpndType *)malloc(STACK_INIT_SIZE*sizeof(OpndType));
if (!S.base)
exit(ERROR);
S.top = S.base; //栈顶指向栈底
S.stackSize = STACK_INIT_SIZE;
return OK;
}
//判断S是否为空栈
Status OpndStackEmpty(OpndStack &S){
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
//若栈不为空 则e返回S的栈顶元素 并返回OK 否则ERROR
Status GetOpndTop(OpndStack S, OpndType &e){
if (S.top > S.base){
e = *(S.top - 1);
return OK;
}
else
return ERROR;
}
//插入e为新的栈顶元素
Status OpndPush(OpndStack &S, OpndType e){
if (S.top - S.base == S.stackSize){
//栈满 追加存储空间
S.base = (OpndType*)realloc(S.base, (S.stackSize + STACKINCREMENT)*sizeof(OpndType));
if (!S.base)
exit(ERROR);
S.top = S.base + S.stackSize; //修改栈顶指针
S.stackSize += STACKINCREMENT; //更新容量
}
*(S.top++) = e;
return OK;
}
//若栈不为空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERROR
Status OpndPop(OpndStack &S, OpndType &e){
if (S.top == S.base) return ERROR;
e = *--S.top;
return OK;
}
//划分优先级
int Rank(OptrType e){
switch (e){
case '#':
return 0; break;
case '(':
return 1; break;
case '+':
case '-':
return 2; break;
case '*':
case '/':
return 3; break;
default:
return INFEASIBLE; break;
}
}
//运算操作
OpndType Operate(OpndType a, OpndType b, OptrType op){
OpndType c;
switch (op){
case '+':
c = a + b;
break;
case '-':
c = a - b;
break;
case '*':
c = a*b;
break;
case '/':
if (b == 0){
printf("分母为0");
return ERROR;
}
else
c = a / b;
break;
default:
printf("输入的字符不合法");
break;
}
return c;
}
Status StackTraverse(OpndStack S){
while (S.top > S.base){
printf("%d ", *(S.base++));
}
printf("\n");
return OK;
}
Status StackTraverse1(OptrStack S){
while (S.top > S.base){
printf("%c ", *(S.base++));
}
printf("\n");
return OK;
}
//将存储表达式的字符数组压入栈内
void HandleStr(char str[]){
OptrStack optr; //定义操作符栈
OpndStack opnd; //定义操作数栈
OptrType op;
InitOptrStack(optr); //初始化操作符栈
InitOpndStack(opnd); //初始化操作数栈
int i, j;
OpndType f, a, b,result;
char num[100];
OptrPush(optr, '#');
for (i = 0; str[i]; i++){
switch (str[i]){
case '+':
case '-':
/*先判断当前运算符与操作符栈栈顶元素的优先级,
如果高于栈顶元素,则入栈;
小于栈顶元素,则从操作数栈中依次出两个数,
并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,
按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,
再将当前的操作符压入操作符栈中。*/
GetOptrTop(optr, op);
if (op == '#' || op == '('){
OptrPush(optr, str[i]);
}
else{
OpndPop(opnd, a);
OpndPop(opnd, b);
OptrPop(optr, op);
OpndPush(opnd, Operate(b, a, op));
OptrPush(optr, str[i]);
}
break;
case '*':
case '/':
GetOptrTop(optr, op);
if (Rank(str[i]) > Rank(op) || op == '('){
OptrPush(optr, str[i]);
}
else{
OpndPop(opnd, a);
OpndPop(opnd, b);
OptrPop(optr, op);
OpndPush(opnd, Operate(b, a, op));
OptrPush(optr, str[i]);
}
break;
case '(':
OptrPush(optr,str[i]);
break;
case ')':
GetOptrTop(optr, op);
while (op != '('){
OpndPop(opnd, a);
OpndPop(opnd, b);
OptrPop(optr, op);
OpndPush(opnd, Operate(b, a, op));
GetOptrTop(optr, op);
}
OptrPop(optr, op);
break;
default:
j = 0;
do{
num[j] = str[i];
i++;
j++;
} while (str[i] > '0' && str[i] < '9' || str[i] == '.');
num[j] = '\0';
i--;
f = atof(num);
OpndPush(opnd, f);
break;
}
}
GetOptrTop(optr, op);
while (op != '#'){
OpndPop(opnd, a);
OpndPop(opnd, b);
OptrPop(optr, op);
OpndPush(opnd, Operate(b, a, op));
GetOptrTop(optr, op);
}
GetOpndTop(opnd, result);
printf("表达式%s=%g\n", str, result);
}
int main(){
char str[100];
printf("请输入表达式:\n");
scanf("%s", str);
HandleStr(str);
return 0;
}