顺序栈的应用:表达式求值
2015-11-22 22:55
288 查看
//顺序栈的应用:表达式求值 //允许用户输入空格(系统自动删除),只能进行整数的四则运算,支持小括号 //对不能整除的将按两个整数除法规则进行取整 #include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define BUFFERSIZE 256 typedef int Status; //函数返回状态 typedef int opndElem; //操作数元素类型 typedef struct{//操作数栈结构定义 opndElem *base; opndElem *top; int stacksize; }OpndStack; typedef char optrElem;//操作符元素类型 typedef struct{//操作符栈结构定义 optrElem *base; optrElem *top; int stacksize; }OptrStack; //==========操作数栈=============// Status InitStack_OPND(OpndStack *S); //构造一个空栈S Status GetTop_OPND(OpndStack S,opndElem *e); //若栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回FALSE Status Push_OPND(OpndStack *S,opndElem e); //插入元素e为新的栈顶元素 Status Pop_OPND(OpndStack *S,opndElem *e); //若栈S不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR //==========操作符栈=============// Status InitStack_OPTR(OptrStack *S); //构造一个空栈S optrElem GetTop_OPTR(OptrStack S); //若栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回FALSE Status Push_OPTR(OptrStack *S,optrElem e); //插入元素e为新的栈顶元素 Status Pop_OPTR(OptrStack *S,optrElem *e); //若栈S不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR //============运算操作================// void Standard(char *expression); //将表达式标准化 opndElem EvalueateExpression(const char *expression); //算数表达式求值 Status Isoperator(char c); //判断c是否是一个操作符 char Precede(char op1,char op2); //判断op1和op2优先级的高低,返回'>','<','=' opndElem operate(opndElem a,optrElem theta,opndElem b); //对操作数a,b进行theta运算 const char *getOpnd(const char *c,opndElem *op); //获得以*c开始的操作数,返回后c为操作符 int main() { opndElem result=0; char *expression=(char*)malloc(sizeof(char)*BUFFERSIZE); if(expression==NULL){ printf("Sorry,memory initialize error.\n"); exit(0); } printf("Please input an expression:\n"); gets(expression); //printf("Before standard:%s\n",expression); Standard(expression);//标准化 //printf("Standard expression:%s\n",expression); result=EvalueateExpression(expression); printf("The result of the expression:%d\n",result); return 0; } //==========操作数栈===========// Status InitStack_OPND(OpndStack *S){ //构造一个空操作数栈S S->base=(opndElem *)malloc(STACK_INIT_SIZE*sizeof(opndElem)); if(!S->base)//分配失败 { printf("分配内存失败.\n"); exit(0); } S->top=S->base; S->stacksize=STACK_INIT_SIZE; return OK; } Status GetTop_OPND(OpndStack S,opndElem *e){ //若操作数栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回FALSE if(S.top==S.base){ printf("栈为空.\n"); return FALSE; }else{ *e=*(S.top-1); return OK; } } Status Push_OPND(OpndStack *S,opndElem e){ //插入元素e为新的栈顶元素 if(S->top-S->base>=S->stacksize){//栈已满,追加存储空间 S->base=(opndElem *)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(opndElem)); if(!S->base) { printf("重新申请空间失败.\n"); exit(0); } S->top=S->base+S->stacksize;//更改栈顶指针 S->stacksize+=STACKINCREMENT; } *S->top++=e; return OK; } Status Pop_OPND(OpndStack *S,opndElem *e){ //若栈S不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR if(S->top==S->base){//栈为空 printf("栈为空.\n"); return ERROR; } *e=*(--S->top); return OK; } //==========操作符栈===========// Status InitStack_OPTR(OptrStack *S){ //构造一个空操作数栈S S->base=(optrElem *)malloc(STACK_INIT_SIZE*sizeof(optrElem)); if(!S->base)//分配失败 { printf("分配内存失败.\n"); exit(0); } S->top=S->base; S->stacksize=STACK_INIT_SIZE; return OK; } optrElem GetTop_OPTR(OptrStack S){ //若操作数栈不为空,则返回S的栈顶元素,并返回OK;否则返回FALSE optrElem e; if(S.top==S.base){ printf("栈为空.\n"); }else{ e=*(S.top-1); } return e; } Status Push_OPTR(OptrStack *S,optrElem e){ //插入元素e为新的栈顶元素 if(S->top-S->base>=S->stacksize){//栈已满,追加存储空间 S->base=(optrElem *)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(optrElem)); if(!S->base) { printf("重新申请空间失败.\n"); exit(0); } S->top=S->base+S->stacksize;//更改栈顶指针 S->stacksize+=STACKINCREMENT; } *S->top++=e; return OK; } Status Pop_OPTR(OptrStack *S,optrElem *e){ //若栈S不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR if(S->top==S->base){//栈为空 printf("栈为空.\n"); return ERROR; } *e=*(--S->top); return OK; } //============运算操作================// opndElem EvalueateExpression(const char *expression){ //对只有四则运算符的算数表达式 expression 求值 //OPTR:操作符栈,OPND:操作数栈 const char *c=expression; OpndStack OPND; OptrStack OPTR; optrElem x,theta; opndElem a,b,num,result; InitStack_OPTR(&OPTR);//初始化操作符栈 InitStack_OPND(&OPND);//初始化操作数栈 Push_OPTR(&OPTR,'#');//首先将匹配符号'#'入栈 while(*c!='#'||GetTop_OPTR(OPTR)!='#'){ //printf("getchar=%c\n",*c); if(*c=='\0')//遇到回车退出 break; if(FALSE==Isoperator(*c)){ c=getOpnd(c,&num); Push_OPND(&OPND,num); } else switch(Precede(GetTop_OPTR(OPTR),*c)){ case '<': Push_OPTR(&OPTR,*c); c++; break; case '=': Pop_OPTR(&OPTR,&x); c++; break; case '>': Pop_OPTR(&OPTR,&theta); Pop_OPND(&OPND,&b); Pop_OPND(&OPND,&a); result=operate(a,theta,b); //printf("temp result is:%d\n",result); Push_OPND(&OPND,result); break; default: //printf("Precede:%c",Precede(GetTop_OPTR(OPTR),*c)); break; }//switch }//while GetTop_OPND(OPND,&result); return result; } void Standard(char *expression){ //将字符串表达式标准化为算术表达式 char *p=expression,*q; while(*p!='\0'){//遍历字符串 if(*p==' '){//如果是空格,删除 q=p; do{ *q=*(q+1); q++; }while(*q!='\0'); } p++; } *p++='#'; *p='\0'; } const char *getOpnd(const char *c,opndElem *op){ //获得以*c开始的操作数,返回后c为操作符 int sum=0,tmp; while(FALSE==Isoperator(*c)){//当c不是操作符 tmp=*c-'0'; sum=sum*10+tmp; //printf("tmp=%d\n",tmp); c++; } *op=sum; //printf("getOpnd:%d\n",*op); return c; } Status Isoperator(char c){ //判断c是否是一个运算操作符 switch(c){ case '+': case '-': case '*': case '/': case '(': case ')': case '#': return TRUE; break; default: return FALSE; break; } } char Precede(char op1,char op2){ //判断op1和op2优先级的高低,返回'>','<','=' switch(op1){ case '+': switch(op2){ case '*': case '/': case '(': return '<'; break; default: return '>'; break; } break; case '-': switch(op2){ case '*': case '/': case '(': return '<'; break; default: return '>'; break; } break; case '*': switch(op2){ case '(': return '<'; break; default: return '>'; break; } break; case '/': switch(op2){ case '(': return '<'; break; default: return '>'; break; } break; case '(': switch(op2){ case ')': return '='; break; default: return '<'; break; } break; case ')': switch(op2){ default: return '>'; break; } break; case '#': switch(op2){ case '#': return '='; break; default: return '<'; break; } break; default: return '<'; break; } } opndElem operate(opndElem a,optrElem theta,opndElem b){ //对操作数a,b进行theta运算,并返回运算结果 //theta只能是四则运算符号 int rs_i; switch(theta){ case '+': rs_i=a+b; break; case '-': rs_i=a-b; break; case '*': rs_i=a*b; break; case '/': if(b==0){ printf("errror:除数为0."); exit(0); } rs_i=a/b; break; default: printf("Is not a operator.\n"); break; } printf("%d %c %d = %d\n",a,theta,b,rs_i); return rs_i; }
相关文章推荐
- Android实践项目汇报(三)
- 信息安全系统设计基础第十一周学习总结
- css sprites
- 20135223何伟钦—信息安全系统设计基础第十一周学习总结
- AngularJs $animate 让页面动起来
- 树莓派入门(一)
- yii2引入第三方类
- Xib自定义cell注意点
- 肇庆游记
- 常见排序算法的C语言实现之堆排序
- PHP 源码编码标准
- Android 中文文档
- 【工具】Netperf 的使用
- 线性代数A矩阵乘以A的转置的含义或者几何意义
- 张孝祥_Java多线程与并发库高级应用03
- Shiro简介与Hello World实现
- 栈的应用之表达式求值
- Core Date的学习建议
- 不安装oracle11g客户端,用plsql连接oracle11g
- Android中dip、dp、sp、pt和px的区别