#include<stdio.h>#include<stdlib.h>#define STACKMAX 50/*栈元素的最大存储结构*/#define TRUE 1#define FALSE 0typedef char elemType;typedef struct stack/*定义栈结构*/{ elemType elem[STACKMAX];/*存储栈元素的数组*/ int top;/*栈顶元素的下标*/}stack;/*栈的初始化*/void init(stack* s){ s->top = 0;}/*压入元素入栈*/int push(stack* s,char x){ if( s->top == STACKMAX ) return FALSE; else { s->top = s->top + 1; s->elem[s->top] = x; return TRUE; }}/*元素出栈*/elemType pop(stack* s){ if(s->top == 0) return NULL; else { s->top = s->top - 1; return s->elem[s->top+1]; }}/*取栈顶元素*/elemType gettop(stack* s){ if(s->top == 0) return NULL; else return s->elem[s->top];}/* 判断操作符op1与操作符op2的优先级 * 如果op1优先于op2,则返回'>' * 如果op2优先于op1,则返回'<' * 如果op1与op2的优先级相同,则返回'=' */char precede(char op1, char op2){ switch(op1) { case '+': case '-': if(op2 == '+' || op2 == '-' || op2 == ')' || op2 == '#') return '>'; else return '<'; case '*': case '/': if( op2 == '(') return '<'; else return '>'; case '(': if(op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == '(') return '<'; else if(op2 == ')') return '='; break; case ')':if(op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == ')' || op2 == '#') return '>'; break; case '#':if(op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == '(') return '<'; else if(op2 == '#') return '='; break; default: return NULL; }}/* 计算操作并且返回结果 * a为第一个操作数 * b为第二个操作数 * theta为操作符 */int operate(int a, char theta, int b){ int c; switch(theta) { case '+': c = a + b; break; case '-': c = a - b; break; case '*': c = a * b; break; case '/': c = a / b; break; default:break; } return c;}/* 本算法的核心函数 */int exp_reduced(){ stack *optr;/* 操作符栈 */ stack *opnd;/* 操作数栈 */ char w;/* 记录用户输入的字符 */ int a,b;/* 记录每次计算的两个操作数 */ char theta;/* 记录每次计算的操作符 */ if ((optr=(stack*)malloc(sizeof(stack))) == NULL) { printf("overflow!\n"); exit(1); } if ((opnd=(stack*)malloc(sizeof(stack))) == NULL) { printf("overflow!\n"); exit(1); } init(optr);/* 初始化 */ init(opnd); push(optr,'#');/* 将表达式左端的虚设字符’#’压入栈 */ scanf("%c",&w);/* 读入第一个字符 */ while ( !(w == '#' && gettop(optr) == '#'))/* 当用户输入的不是结束字符'#'并且操作符栈不为空时循环*/ { /* 如果输入的字符是数字遍压入数字栈,并且输入下个字符 */ if ( w >= '0' && w <='9') { push(opnd,w - '0'); scanf("%c",&w); } else/* 输入的是操作符 */ { switch ( precede(gettop(optr), w) )/* 比较输入的操作符与操作符栈顶元素的优先级 */ { case '<': push(optr,w);/* 输入的操作符优先级小于栈顶元素优先级,将输入的操作符压入栈 */ scanf("%c",&w);/* 输入下一个字符 */ break; case '=': pop(optr);/* 消去括号 */ scanf("%c",&w); break; case '>': theta = pop(optr);/*输入的操作符优先级大于栈顶元素的优先级,取出数字栈的两个元素进行计算,结果再压入数字栈*/ b = pop(opnd); a = pop(opnd); push(opnd, operate(a,theta,b)); break; default:break; } } } free(optr); free(opnd); return gettop(opnd);/* 返回计算的结果 */}main(){ int result; result = exp_reduced(); printf("%d\n",result);}