#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREASMENT 10
#define OVERFLOW -1
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
typedef int SElemType_int;
typedef char SElemType_char;
typedef int Status;
typedef struct
{
SElemType_int* base, * top;
int stacksize;
}SqStack_int; //需要两种栈,一种是数值栈,一种是符号栈
typedef struct
{
SElemType_char* base, * top;
int stacksize;
}SqStack_char;
Status Push_int(SqStack_int* S, SElemType_int e)
{
if (S->top - S->base >= S->stacksize)
{
SElemType_int* base;
base = (SElemType_int*)realloc(S->base, (S->stacksize + STACKINCREASMENT) * sizeof(SElemType_int));
if (!base) exit(OVERFLOW);
S->base = base;
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREASMENT;
}
*S->top = e;
S->top++;
return OK;
}
Status Pop_int(SqStack_int* S, SElemType_int* e)
{
if (S->top == S->base) return ERROR;
S->top--;
*e = *S->top;
return OK;
}
Status InitStack_int(SqStack_int* S)
{
S->base = (SElemType_int*)malloc(sizeof(SElemType_int) * STACK_INIT_SIZE);
if (!S->base) exit(OVERFLOW);
S->top = S->base;
S->stacksize = 0;
return OK;
}
Status GetTop_int(SqStack_int* S, SElemType_int* e)
{
if (S->base == S->top) return ERROR;
*e = *(S->top - 1);
return OK;
}
Status StackEmpty_int(SqStack_int* S)
{
if (S->base == S->top) return TRUE;
else return FALSE;
}
Status Push_char(SqStack_char* S, SElemType_char e)
{
if (S->top - S->base >= S->stacksize)
{
SElemType_char* base;
base = (SElemType_char*)realloc(S->base, (S->stacksize + STACKINCREASMENT) * sizeof(SElemType_char));
if (!base) exit(OVERFLOW);
S->base = base;
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREASMENT;
}
*S->top = e;
S->top++;
return OK;
}
Status Pop_char(SqStack_char* S, SElemType_char* e)
{
if (S->top == S->base) return ERROR;
S->top--;
*e = *S->top;
return OK;
}
Status InitStack_char(SqStack_char* S)
{
S->base = (SElemType_char*)malloc(sizeof(SElemType_char) * STACK_INIT_SIZE);
if (!S->base) exit(OVERFLOW);
S->top = S->base;
S->stacksize = 0;
return OK;
}
Status GetTop_char(SqStack_char* S, SElemType_char* e)
{
if (S->base == S->top) return ERROR;
*e = *(S->top - 1);
return OK;
}
Status StackEmpty_char(SqStack_char* S)
{
if (S->base == S->top) return TRUE;
else return FALSE;
}
int code(char a) //为每一个符号对应一个数字,以便在优先级表中
{ //查阅
switch (a)
{
case '+':return 0; break;
case'-':return 1; break;
case'*':return 2; break;
case'/':return 3; break;
case'(':return 4; break;
case')':return 5; break;
default:return 6;
}
}
char Precede(char a, char b)
{
char link[7][7] =
{
{'>','>','<','<','<','>','>'}, //优先级表,>代表优先
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=',' '},
{'>','>','>','>',' ','>','>'},
{'<','<','<','<','<',' ','='}
};
int i, j;
j = code(b);
i = code(a);
return link[i][j];
}
int Operate(int a, char b, int c) //定义两个操作数与一个操作符相遇
{ //应该怎样去计算
switch (b)
{
case '+':return a + c; break;
case '-':return a - c; break;
case '/':return a / c; break;
default:return a * c;
}
}
int EvaluteExpression()
{
SqStack_char OPTR;
SqStack_int OPND;
InitStack_char(&OPTR); //建立运算符栈
InitStack_int(&OPND); //建立运算数栈
Push_char(&OPTR, '#'); //以‘#’作为运算结束标志
int i, j, k;
int bool = TRUE; //用于判定已经输入的操作符是否入栈
char c,d,e; //因为如果操作符栈顶元素优先级大于
do //已输入操作符,先要进行Operate
{ //然后再将刚刚未入栈的低优先级操作符
if (bool == TRUE) //重新入栈
{
printf("决定是输入操作数还是操作符,用0与1来区分二者\n");
scanf("%d", &i);
}
if (i == 0)
{
printf("请输入操作数\n");
scanf("%d", &j);
Push_int(&OPND, j);
}
else
{
if (bool == TRUE)
{
printf("请输入操作符\n");
getchar(); //接收上面的scanf最后的回车符
c = getchar();
}
GetTop_char(&OPTR, &d);
switch (Precede(d,c)) //将栈顶的运算符与输入运算符比较优
{ //先级
case '<': //栈顶元素优先级小,入栈
Push_char(&OPTR, c);
bool = TRUE;
break;
case'=': //优先级相同,弹出栈顶元素,且这个元
Pop_char(&OPTR, &c); //且新输入元素也无需入栈
bool = TRUE;
break;
case'>': //栈顶元素优先级大,先进行运算
Pop_char(&OPTR, &e); //在下一个循环将操作符入栈
Pop_int(&OPND, &j);
Pop_int(&OPND, &k);
Push_int(&OPND, Operate(k, e, j));
bool = FALSE;
break;
}
}
} while (i != 1 || c != '#' || d != '#'); //最开始c与d都不存在所以有第一个条件
GetTop_int(&OPND, &i); //当输入#想结束运算时,只有栈顶元素
return i; //也为#然后Pop出去才能真正结束运算
}
//主函数
int main()
{
int i;
i = EvaluteExpression();
printf("结果为:%d\n", i);
return 0;
}
输入:(严蔚敏P52表达式求值:4+2*3-10/5)
0
4
1
+
0
2
1
*
0
3
1
-
0
10
1
/
0
5
1
#
输出: