借助栈实现表达式的计算
来源:互联网 发布:mac如何收藏网页的图片 编辑:程序博客网 时间:2024/05/20 18:44
这两天要复习准备考试,博客没有及时更新。另一方面,后缀表达式的转化及求值的程序始终没有写好,让我异常苦恼,心情也是莫名烦躁。现在表达式求值的程序已基本实现,仍有不足之处需要改进,各位可以参考,由于时间关系,无法细致讲解。将在考完试后的更新中加以补充,各位先看代码后的注释吧,注释还是比较详细的,代码如下
#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100#define MAXOP 32typedef char elemtype;typedef int status;/*定义运算符优先级*/typedef struct calc{ elemtype ch; int pri;}calc;/*同一运算符在栈内和栈外优先级不同,需要加一个数字进行区分*/calc inpri[]={{'=',0},{'(',1},{'*',5},{'/',5},{'+',3},{'-',3},{')',6}};calc outpri[]={{'=',0},{'(',6},{'*',4},{'/',4},{'+',2},{'-',2},{')',1}};/*定义运算符栈*/typedef struct sqstack{ elemtype data[MAXSIZE]; int top;}sqstack;/*定义运算结果栈*/ typedef struct value{ float suffixvalue[MAXSIZE]; int top;}value;/*定义栈操作***************************************/status traversestack(sqstack *s){ int i=0; for(i=s->top;i>=0;i--){ printf("%d ",s->data[i]); } printf("\n");}/*初始化运算符栈*/ status initstack(sqstack *s){ s->top=-1;//置空栈 }/*初始化运算结果栈*/ status initvstack(value *V){ V->top=-1; return OK;}//将元素压入栈 status push(sqstack *s,elemtype data){ if(s->top==MAXSIZE-1){ return ERROR;//判断栈是否已满 } else{ s->top++; s->data[s->top]=data; } return OK;}//返回栈长status stacklength (sqstack *s){ return s->top+1;}//出栈status pop(sqstack *s,elemtype * data){ if(s->top==-1){ printf("空栈\n"); return ERROR; } else{ *data=s->data[s->top]; s->top--; }}/*取栈顶元素*/status gettop(sqstack *S,elemtype *ch){ if(S->top==-1) return ERROR; else *ch=S->data[S->top]; return OK;}/*定义栈操作结束 ***************************************//*定义运算符相关操作****************************************//*求栈外操作符优先级*/status Inpri(elemtype op){ int i=0; for(i=0;i<MAXOP;i++){ if(op==inpri[i].ch) return inpri[i].pri; }} /*求栈内操作符优先级*/status Outpri(elemtype op){ int i=0; for(i=0;i<MAXOP;i++){ if(op==outpri[i].ch) return outpri[i].pri; }}/*判断两运算符优先级关系*/status precede(elemtype opin,elemtype opout){ if(Inpri(opin)>Outpri(opout)) return 1; else if(Inpri(opin)<Outpri(opout)) return -1; else return 0;}/*判断是否为运算符*/status isop(elemtype ch){ if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return TRUE; else return FALSE; }/*将中缀表达式转换为后缀表达式*/status trans(char * infix,char suffix[]){ sqstack S; initstack(&S); push(&S,'=');/*先让一个等号入栈,作为标记*/ char ch; int i=0,j=0; while(*infix!='\0'){ /*是数字的情况*/ if(!isop(*infix)){ while((*infix)>='0'&&(*infix)<='9'){ suffix[j++]=*infix; infix++; } suffix[j++]='#';/*数字与数字之间用空格隔开*/ } /*是运算符的情况*/ else{ gettop(&S,&ch); switch(precede(ch,*infix)){ case 1:/*栈顶高于栈外*/ suffix[j++]=ch;/*栈顶出栈直到栈顶元素优先级低于栈外为止*/ pop(&S,&ch); //infix++;/*向后遍历*/ break; case 0:/*栈顶等于栈外,只有括号会出现此情况*/ pop(&S,&ch);/*直接出栈*/ infix++; break; case -1:/*栈顶低于栈外*/ push(&S,*infix);/*入栈即可*/ infix++; break; } } }/*while(*infix!='/0')*/ /*循环结束,开始输出后缀表达式*/ pop(&S,&ch); while(ch!='='){/*等号代表了表达式的开头*/ suffix[j++]=ch; pop(&S,&ch); }}/*计算后缀表达式的值*/float compute(char suffix[]){ value V; initvstack(&V); char ch; int t=0; float d; ch=suffix[t]; t++; while(ch!='\0'){ /*让栈顶两元素出栈进行运算*/ switch(ch){ case '+': V.suffixvalue[V.top-1]=V.suffixvalue[V.top-1]+V.suffixvalue[V.top]; V.top--; break; case '-': V.suffixvalue[V.top-1]=V.suffixvalue[V.top-1]-V.suffixvalue[V.top]; V.top--; break; case '/': if(V.suffixvalue[V.top]){ V.suffixvalue[V.top-1]=V.suffixvalue[V.top-1]/V.suffixvalue[V.top]; V.top--; break; } else{ printf("除零错误\n"); return ERROR; } case '*': V.suffixvalue[V.top-1]=V.suffixvalue[V.top-1]*V.suffixvalue[V.top]; V.top--; break; /*如果后缀表达式中有数字*/ default: d=0; while(ch>='0'&&ch<='9'){ d=10*d+ch-'0';/*将字符转换成数字*/ ch=suffix[t];/*向后遍历*/ t++; } V.top++; V.suffixvalue[V.top]=d;/*将转换好的入栈*/ } ch=suffix[t];/*更新ch的值*/ t++; } return V.suffixvalue[V.top];/*返回栈顶值作为运算结果*/ }int main(void){ char infix[]="(56-20)/(4+2)"; char suffix[200]; trans(infix,suffix); printf("中缀表达式:%s\n",infix); printf("后缀表达式:%s\n",suffix); printf("后缀表达式的值为%f",compute(suffix)); return 0;}
再次吐槽:真心难啊…………
2016-04-21日更新:
今天复习了表达式求值问题,还是感到存在一些问题,还是对算法的理解理解不够透彻造成的。
问题主要出现在后缀表达式转中缀表达式的过程中
status trans(char *infix,char suffix[]){ elemtype ch; sqstack S; int i=0; initstack(&S); push(&S,'='); while(*infix!='\0'){ if(!isop(*infix)){ while(*infix<='9'&&*infix>='0'){ suffix[i++]=*infix; infix++; } suffix[i++]='#'; } else{ gettop(&S,&ch); switch(precede(ch,*infix)){ case 1: suffix[i++]=ch; pop(&S,&ch); break; case 0: pop(&S,&ch); infix++; break; case -1: push(&S,*infix); infix++; break; } } }/*while(*infix!='\0')*/ pop(&S,&ch); suffix[i]=ch; while(ch!='='){ suffix[i++]=ch; pop(&S,&ch); }}
在这段代码的switch语句中,在处理case 0时,对于括号的优先级的理解有所遗忘。正确的处理方式是当栈外为右括号,栈内为左括号时,直接出栈即可。
在compute函数中,忘了写default语句,导致当遇到后缀表达式中的数字时无法处理。
以上就是今天的错误,要引以为戒。
0 0
- 借助栈实现表达式的计算
- 栈实现表达式的计算
- 栈实现表达式计算
- 表达式计算栈实现
- 栈实现后缀表达式的计算
- 使用栈实现整型表达式的计算
- 通过栈实现算术表达式的计算
- 用栈来实现表达式的计算
- C++实现表达式的计算
- 借助栈实现单链表逆置
- 用栈实现表达式计算
- 用栈实现表达式计算
- 表达式计算,输出后缀表达式,栈实现
- 完全利用栈实现表达式的计算问题
- 使用栈计算多项表达式的简单实现--java
- 借用栈实现表达式的转换与计算
- 【数据结构】用栈实现对后缀表达式的计算
- C++实现:用栈实现表达式计算
- HDU 2569 彼岸(递推)
- Ubuntu 的应用程序都在哪里
- Python 标准库 —— xml
- CodeForces-545C Woodcutters 【贪心+机智】
- Intent来传递对象
- 借助栈实现表达式的计算
- [Java 并发] 线程的基本知识(一)
- iOS多边形按键的创建
- 两种配置大数据环境的方法Ambari以及hadoop源代码安装的步骤
- 在其他class或者view中获取MainActivity实例,以便调用其函数的方法:
- row_number() OVER(PARTITION BY)函数介绍
- Scrapy入门教程之写入数据库
- 实习过程中linux相关开发学习总结(二)
- mac osx下 atom 插件推荐